你这个学期必须选修 numCourse 门课程,记为 0 到 numCourse-1 。
在选修某些课程之前需要一些先修课程。 例如,想要学习课程 0 ,你需要先完成课程 1 ,我们用一个匹配来表示他们:[0,1]
给定课程总量以及它们的先决条件,请你判断是否可能完成所有课程的学习?
示例 1:
输入: 2, [[1,0]] 输出: true 解释: 总共有 2 门课程。学习课程 1 之前,你需要完成课程 0。所以这是可能的。 示例 2:
输入: 2, [[1,0],[0,1]] 输出: false 解释: 总共有 2 门课程。学习课程 1 之前,你需要先完成课程 0;并且学习课程 0 之前,你还应先完成课程 1。这是不可能的。
来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/course-schedule 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解法:判断有咩有环,可以使用拓扑排序,也可以使用深度遍历,深度遍历需要标记,需要三种标记,需要剪枝,访问到已经访问过的没有问题的就可以直接返回
class Solution {
public:
bool canFinish1(int numCourses
, vector
<vector
<int>>& prerequisites
) {
if(numCourses
< 2 || prerequisites
.size() == 0)
return true;
map
<int,vector
<int>> G
;
map
<int,int> indegree
;
int count
= 0;
for(int i
=0;i
<prerequisites
.size();i
++){
G
[prerequisites
[i
][1]].push_back(prerequisites
[i
][0]);
indegree
[prerequisites
[i
][0]]++;
}
stack
<int> zeroStack
;
for(int i
=0;i
<numCourses
;i
++){
if(indegree
.find(i
) == indegree
.end() || indegree
[i
] == 0){
zeroStack
.push(i
);
}
}
while(!zeroStack
.empty()){
int node
= zeroStack
.top();
count
++;
zeroStack
.pop();
for(auto &num
:G
[node
]){
indegree
[num
]--;
if(indegree
[num
] == 0){
zeroStack
.push(num
);
}
}
}
return count
== numCourses
;
}
bool canFinish(int numCourses
, vector
<vector
<int>>& prerequisites
) {
map
<int,vector
<int>> G
;
vector
<int> flag(numCourses
,0);
for(int i
= 0;i
< prerequisites
.size();i
++){
G
[prerequisites
[i
][0]].push_back(prerequisites
[i
][1]);
}
for(int i
=0;i
<numCourses
;i
++){
if(!dfs(i
,G
,flag
))
return false;
}
return true;
}
bool dfs(int node
,map
<int,vector
<int>>& G
,vector
<int>& flag
){
if(flag
[node
] == -1){
return true;
}
if(flag
[node
] == 1){
return false;
}
flag
[node
] = 1;
for(auto& num
: G
[node
]){
if(!dfs(num
,G
,flag
))
return false;
}
flag
[node
] = -1;
return true;
}
};