问题:
给定编号为:0~numCourses-1 ,numCourses门课。
以及课程依赖关系:prerequisites,prerequisites[x][0] 依赖 prerequisites[x][1]
即得先上 prerequisites[x][1] 课程,才能上prerequisites[x][0]
如果存在双方互相依赖,那么无法上这两科。
求是否能够顺利上所有的课。
Example 1: Input: numCourses = 2, prerequisites = [[1,0]] Output: true Explanation: There are a total of 2 courses to take. To take course 1 you should have finished course 0. So it is possible. Example 2: Input: numCourses = 2, prerequisites = [[1,0],[0,1]] Output: false Explanation: There are a total of 2 courses to take. To take course 1 you should have finished course 0, and to take course 0 you should also have finished course 1. So it is impossible. Constraints: 1 <= numCourses <= 105 0 <= prerequisites.length <= 5000 prerequisites[i].length == 2 0 <= ai, bi < numCourses All the pairs prerequisites[i] are unique.
解法:BFS
检查:有向图是否存在有向环。
若存在,则返回false,不存在返回true。
对于本题:通过依赖关系prerequisites,构建图:node
若:node[x][y]==1,那么有 x->y
若:node[x][y]==0,那么有 x,y之间无直接相连。
同时,对每个节点x计算入度indegree[x]
⚠️ 注意:如果 已经有node[x][y]==1,不要将入度重复计算。
开始遍历图:
首先,将所有入度为0的节点,加入queue中。
(那么这些节点就是开始节点,只有出度)
对每一个当前节点x:将他的直连if (node[x][y]==1)节点 y:
入度--:indegree[y]--
若这时,y的入度全部走完,那么:
节点y加入queue中,等待下一层遍历。
⚠️ 若遍历完,剩下很多节点,入度都!=0,那就说明,出现了♻️ 有向环。
代码参考:
1 class Solution { 2 public: 3 bool canFinish(int numCourses, vector<vector<int>>& prerequisites) { 4 vector<vector<int>> node(numCourses, vector<int>(numCourses, 0)); 5 queue<int> q; 6 vector<int> indegree(numCourses,0); 7 int count = 0; 8 for(vector<int> pq:prerequisites) { 9 if(node[pq[1]][pq[0]]==0) indegree[pq[0]]++;//防止重复,使得入度多算 10 node[pq[1]][pq[0]]=1; 11 } 12 for(int i=0; i<numCourses; i++) { 13 //加入所有入度=0的节点。从这些节点开始,出度 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 count++; 21 q.pop(); 22 for(int j=0; j<numCourses; j++) { 23 if(node[cur][j]==1) { 24 indegree[j]--; 25 if(indegree[j]==0) q.push(j);//若当前节点j入度=0,则加入queue中。 26 } 27 } 28 } 29 } 30 if(numCourses!=count) return false; 31 else return true; 32 } 33 };