方法一:1、建立图 2、对节点进行依次判别所形成的通路是否为环形结构,如果是则返回
inpath负责标记在寻找通路时对通路的标记,注意回溯的位置,应该是在for循环之后、visisted负责标记已经遍历过的节点,减少多余的遍历,若没有visited计算复杂度将大大增加
class Solution {public:vector<bool> visited;vector<bool> onpath;bool iscycle=false;bool canFinish(int numCourses, vector<vector<int>>& prerequisites) {visited.resize(numCourses);onpath.resize(numCourses);vector<vector<int>> graph=builgraph(numCourses, prerequisites);for(int i=0;i<numCourses;i++){dfs(graph,i);}return !iscycle;}vector<vector<int>> builgraph(int numCourses, vector<vector<int>>& prerequisites){vector<vector<int>>graph;graph.resize(numCourses);for(auto prere:prerequisites){int from=prere[1];int to=prere[0];graph[from].emplace_back(to);}return graph;}void dfs(vector<vector<int>>& graph,int num){if(onpath[num]){iscycle=true;}if(visited[num]||iscycle){return;}visited[num]=true;onpath[num]=true;for(auto g:graph[num]){dfs(graph,g);}onpath[num]=false;}};
方法二:BFS,用inter数组记录每个节点在to中的个数,通过遍历对inter[to]—,若在to中的个数为0则压入队列,用visit记录压入队列的数据的个数,若无循环,则visited与numCourses相同
class Solution {
public:
bool canFinish(int numCourses, vector<vector<int>>& prerequisites) {
queue<int> q;
vector<int>inter;
inter.resize(numCourses);
vector<vector<int>>graph=buildgraph(numCourses,prerequisites,inter);
for(int i=0;i<numCourses;i++){
if(inter[i]==0){
q.emplace(i);
}
}
int visited=0;
while(!q.empty()){
int temp=q.front();
q.pop();
visited++;
for(auto g:graph[temp]){
inter[g]--;
if(inter[g]==0){
q.emplace(g);
}
}
}
return visited==numCourses;
}
vector<vector<int>> buildgraph(int num, vector<vector<int>>& prerequisites,vector<int>& inter){
vector<vector<int>> graph;
graph.resize(num);
for(auto i:prerequisites){
int from=i[1];
int to=i[0];
graph[from].emplace_back(to);
++inter[to];
}
return graph;
}
};
