class Solution {
public:
bool flag = true;
vector<int> visited;
vector<vector<int>> vecVecInt;
bool canFinish(int numCourses, vector<vector<int>>& prerequisites) {
//其实是一个图论问题,看图中是否存在环
//那么我们只要把每个课程看成点, 先修课程关系看成线,然后观察有没有环就可以了
visited.resize(numCourses); //构造numCourses大小的visited数组,记录是否已经访问过该点
vecVecInt.resize(numCourses); //构造numCourses大小的vecVecInt数组,记录该点与其他点的连接关系
for(auto i : prerequisites){ //遍历所有先修课程关系,构造图
vecVecInt[i[0]].push_back(i[1]);
}
for(auto i = 0; i < numCourses && flag; ++i){ //对每个点遍历,观察从该点开始是否存在环
dfs(i);
}
return flag; //flag用作记录全局中是否存在环,默认为true,存在为false
}
void dfs(int n){ //深度遍历图
if(visited[n] == 2) //2表明该点已经访问过了,并且不是环上的点
return;
visited[n] = 1; //标记为该点访问过了
for(auto i : vecVecInt[n]){
if(visited[i] == 0){ //visited == 0 说明还没有访问过
dfs(i); //访问该点
if(!flag) //如果访问之后,flag变为false,说明访问时发现环关系了
return; //快速结束所有访问
}
else if(visited[i] == 1){ //visited == 1 说明之前已经访问过了,这是第二次访问,即存在环关系
flag = false; //发现环关系,flag置为false
return;
}
}
visited[n] = 2; //该点为安全点
}
};
Accepted
51/51 cases passed (24 ms)
Your runtime beats 33.99 % of cpp submissions
Your memory usage beats 23.46 % of cpp submissions (14.1 MB)