Leetcode面试经典150题-207.课程表
这个题是图的问题,因为图的拓扑排序在实际应用中有非常多的用途图,所以最近考的越来越多
解法都在代码里,不懂就留言或者私信
class Solution {
static class Course {
/**可成的入度,就是它依赖的课程数 */
int in;
/**课程的编号 */
int no;
List<Course> nexts;
public Course(int no) {
this.no = no;
this.nexts = new ArrayList<>();
}
}
public boolean canFinish(int numCourses, int[][] prerequisites) {
/**就一个可成不可能有依赖,肯定可以完成,如果依赖表是空也没有任何依赖可以完成 */
if(numCourses == 1 || prerequisites.length == 0) {
return true;
}
/**map用来统计有依赖关系的课程和编号的对应关系,这里是为了我们操作的同一个编号的课程都是同一个对象*/
Map<Integer, Course> map = new HashMap<>();
for(int[] prerequisite : prerequisites) {
/**不管是依赖可成还是被依赖的课程,只要没在map里就new出来 */
if(!map.containsKey(prerequisite[1])) {
map.put(prerequisite[1], new Course(prerequisite[1]));
}
if(!map.containsKey(prerequisite[0])) {
map.put(prerequisite[0], new Course(prerequisite[0]));
}
/**[0]是依赖[1]的,所以这里加到[1]的nexts里 */
map.get(prerequisite[1]).nexts.add(map.get(prerequisite[0]));
/**[0]依赖1,所以[0]的入度加1 */
map.get(prerequisite[0]).in ++;
}
/**遍历Map中的所有数据,把入度为0的先入队*/
Queue<Course> queue = new LinkedList<>();
/**count用来表示完成的课程数*/
int count = 0;
for(Course course : map.values()) {
if(course.in == 0) {
queue.offer(course);
}
}
/**如果队列不为空,把队列里的弹出,每弹出一个,把它的nexts里的课程的入度都减1,如果减完为0,入队 */
while(!queue.isEmpty()) {
/**拿出入度为0的课程,代表它已经完成,别人对他的依赖完成了(依赖消除) */
Course cur = queue.poll();
/**每完成一个,数量+1 */
count ++;
/**把每个依赖它的课程的入度-1 */
for(Course next : cur.nexts) {
next.in --;
/**如果-1之后为0了,它也没有依赖了,入队 */
if(next.in == 0) {
queue.offer(next);
}
}
}
/**我们只是把prerequisites中的依赖关系加入map,不在prerequisites的可以直接完成,不用考虑
所以这里一定要写==map.size() */
return count == map.size();
}
}
结果一般,因为我利用的数据结构太多了,可以自己考虑改成数组或者别的来代替,我这边着急刷,先不优化了,毕竟面试没几个人管你的常数时间