拓扑排序的BFS实现
class Solution {
public boolean canFinish(int numCourses, int[][] prerequisites) {
if (numCourses <= 0) {
return false;
}
// 特判
if (0 == prerequisites.length) {
return true;
}
int[] indegrees = new int[numCourses]; //入度数组
HashSet<Integer>[] adj = new HashSet[numCourses]; //邻接表
for (int i = 0; i < numCourses; i++) {
adj[i] = new HashSet<>();
}
for (int[] path : prerequisites) {
int to = path[0];
int from = path[1]; //先修课程
indegrees[to] ++ ; //统计入度
adj[from].add(to); //建立邻接表
}
Queue<Integer> q = new LinkedList<Integer>();
//入度为0的点加入队列作为起点
for (int i = 0; i < numCourses; i++) {
if(indegrees[i] == 0)
q.offer(i);
}
int count = 0;
while(!q.isEmpty()) {
int course = q.poll();
count++ ;
for (Integer after: adj[course]) {
//将入度为0的点删除后,其邻接点的入度均减1
indegrees[after]-- ;
if(indegrees[after] == 0)
q.offer(after);
}
}
//出队列点的数目是否等于课程数
return count == numCourses;
}
}
题没变,输出拓扑排列的顺序,特判错了好多次。。。
还有就是,要求返回数组的,以后一律用list做,最后遍历一遍链表就行,用数组判断是否越界太繁琐了。
class Solution {
public int[] findOrder(int numCourses, int[][] prerequisites) {
if (numCourses <= 0) {
return new int[] {0};
}
int[] indegrees = new int[numCourses]; //入度数组
HashSet<Integer>[] adj = new HashSet[numCourses]; //邻接表
for (int i = 0; i < numCourses; i++) {
adj[i] = new HashSet<>();
}
for (int[] path : prerequisites) {
int to = path[0];
int from = path[1]; //先修课程
indegrees[to] ++ ; //统计入度
adj[from].add(to); //建立邻接表
}
List<Integer> res = new LinkedList<Integer>();
Queue<Integer> q = new LinkedList<Integer>();
//入度为0的点加入队列作为起点
for (int i = 0; i < numCourses; i++) {
if(indegrees[i] == 0)
q.offer(i);
}
int count = 0;
while(!q.isEmpty()) {
int course = q.poll();
res.add(course);
count++ ;
for (Integer after: adj[course]) {
//将入度为0的点删除后,其邻接点的入度均减1
indegrees[after]-- ;
if(indegrees[after] == 0)
q.offer(after);
}
}
int[] answer = new int[res.size()];
for (int i = 0; i < res.size(); i++) {
answer[i] = res.get(i);
}
//出队列点的数目是否等于课程数
if(count == numCourses)
return answer;
else
return new int[] {};
}
}