问题:
给定编号为0~numCourses-1 的课程,以及课程的依赖关系prerequisites
其中prerequisites[i] = [ai, bi],ai之前必须先上了bi的课程。 bi->ai
若能够上完所有的课程,给出一个上课顺序。
否则,返回空数组。
Example 1: Input: numCourses = 2, prerequisites = [[1,0]] Output: [0,1] Explanation: There are a total of 2 courses to take. To take course 1 you should have finished course 0. So the correct course order is [0,1]. Example 2: Input: numCourses = 4, prerequisites = [[1,0],[2,0],[3,1],[3,2]] Output: [0,2,1,3] Explanation: There are a total of 4 courses to take. To take course 3 you should have finished both courses 1 and 2. Both courses 1 and 2 should be taken after you finished course 0. So one correct course order is [0,1,2,3]. Another correct ordering is [0,2,1,3]. Example 3: Input: numCourses = 1, prerequisites = [] Output: [0] Constraints: 1 <= numCourses <= 2000 0 <= prerequisites.length <= numCourses * (numCourses - 1) prerequisites[i].length == 2 0 <= ai, bi < numCourses ai != bi All the pairs [ai, bi] are distinct.
解法:BFS
有向图遍历,判断是否有内循环♻️ 环。有,则不符合要求。
根据依赖关系prerequisites,构造有向图:graph[node1] = {node2, node3...noden}
- node1 -> node2
- node1 -> node3
- ...
- node1 -> noden
同时记录有向信息,入度数:indegree[node1]=x(count{node2,node3...noden})
- 从入度为0的节点开始遍历图。
- queue.push(nodex(where indegree[nodex]==0))
- for
- 一个个pop节点:cur(同时该节点被遍历,加入res)
- 对cur的所有后续节点graph[cur]: nextn,indegree[nextn]--
- 若后续节点nextn的入度==0,加入queue:queue.push(nextn)
- 继续pop下一个节点。
- 最后res.size!=课程数numCourses,则说明没有遍历完有向图,
- 返回空数组。
- 其他,返回res。
代码参考:
1 class Solution { 2 public: 3 vector<int> findOrder(int numCourses, vector<vector<int>>& prerequisites) { 4 vector<vector<int>> graph(numCourses); 5 vector<int> res; 6 queue<int> q; 7 vector<int> indegree(numCourses, 0); 8 for(auto line:prerequisites) { 9 graph[line[1]].push_back(line[0]); 10 indegree[line[0]]++; 11 } 12 for(int i=0; i<numCourses; i++) { 13 //indegree==0 node has only output. 14 if(indegree[i]==0) q.push(i); 15 } 16 while(!q.empty()) { 17 int sz = q.size(); 18 for(int i=0; i<sz; i++) { 19 int cur = q.front(); 20 q.pop(); 21 res.push_back(cur); 22 for(auto nextn:graph[cur]) { 23 indegree[nextn]--; 24 if(indegree[nextn]==0) q.push(nextn); 25 } 26 } 27 } 28 if(res.size()!=numCourses) return vector<int>(); 29 else return res; 30 } 31 };