题目描述
There are a total of n courses you have to take, labeled from 0
to n-1
.
Some courses may have prerequisites, for example to take course 0 you have to first take course 1, which is expressed as a pair: [0,1]
Given the total number of courses and a list of prerequisite pairs, is it possible for you to finish all courses?
题目大意
判断一个有向图是否存在环。
示例
E1
E2
解题思路
DFS搜索每个结点相连接的结点,用visited数组保存在本轮dfs过程中是否访问过本结点,若访问过则表示出现环。
复杂度分析
时间复杂度:O(|V| + |E|)
空间复杂度:O(|E|)
代码
class Solution { public: bool canFinish(int numCourses, vector<vector<int>>& prerequisites) { vector<unordered_set<int> > map(numCourses); for(int i = 0; i < prerequisites.size(); ++i) { map[prerequisites[i][1]].insert(prerequisites[i][0]); } //保存外围循环中该结点是否在DFS中被访问过 vector<bool> f(numCourses, false); //保存每轮的dfs结点访问情况 unordered_set<int> v; //进行外围的初始结点遍历,对每个尚未被访问的结点调用DFS for(int i = 0; i < numCourses; ++i) { if(!f[i]) if(dfs(map, f, v, i)) return false; } return true; } bool dfs(vector<unordered_set<int> >& pre, vector<bool>& f, unordered_set<int>& v, int k) { f[k] = true; v.insert(k); //依次访问与该结点相连接的结点,并递归调用DFS进行环判断 for(unordered_set<int>::iterator iter = pre[k].begin(); iter != pre[k].end(); ++iter) { //若相连的结点中出现了在本次dfs中的结点,则表明该图存在环 if(v.find(*iter) != v.end() || dfs(pre, f, v, *iter)) return true; } v.erase(k); return false; } };