207. Course Schedule

问题:

给定编号为: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 };

 

posted @ 2021-02-26 15:32  habibah_chang  阅读(61)  评论(0编辑  收藏  举报