利用入度来求
bool canFinish(int numCourses, vector<vector<int>>& prerequisites) {
if(prerequisites.empty()) return true;
vector<int> indegree(numCourses);
//统计各个节点(课程)的入度
for(int i=0;i<prerequisites.size();++i){
++indegree[prerequisites[i][0]];
}
//入度为0的节点就是安全节点
queue<int> q;
for(int i=0;i<numCourses;++i){
if(indegree[i]==0){
q.push(i);
}
}
int cnt = 0;
while(!q.empty()){
//安全节点出队,并用cnt记录
int safe = q.front();
q.pop();
++cnt;
for(int i=0;i<prerequisites.size();++i){
//如果一个节点都是由安全节点指向的,那么该节点也是安全节点,也要入队
if(prerequisites[i][1] == safe){
--indegree[prerequisites[i][0]];
if(indegree[prerequisites[i][0]]==0){
q.push(prerequisites[i][0]);
}
}
}
}
//安全节点全部入队并出队,若都是安全节点,则返回true
return cnt == numCourses;
}
利用dfs来求
class Solution {
public:
bool canFinish(int numCourses, vector<vector<int>>& prerequisites) {
if(prerequisites.empty()) return true;
vector<vector<int>> tmp(numCourses);
//flag:2表示从该节点起无环,1表示正在遍历,0表示还未遍历过
vector<int> flag(numCourses);
//tmp[i]里包含所有i指向的节点
for(int i=0;i<prerequisites.size();++i){
tmp[prerequisites[i][0]].push_back(prerequisites[i][1]);
}
bool ans = true;
for(int i=0;i<numCourses;++i){
ans = ans && dfs(i,flag,tmp);
}
return ans;
}
bool dfs(int i, vector<int> &flag, const vector<vector<int>> &tmp){
if(flag[i]==2)//之前已检验过,从该点起无环,直接返回
return true;
else if(flag[i]==1)//是正在检验的点,说明有环
return false;
flag[i] = 1;//表示正在检验
for(int j=0;j<tmp[i].size();++j){
if(dfs(tmp[i][j],flag,tmp)){
continue;
}
return false;
}
flag[i] = 2;
return true;
}
};