LeetCode-207 Course Schedule

题目描述

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

Input: 2, [[1,0]] 
Output: true

E2

Input: 2, [[1,0],[0,1]]
Output: false

 

解题思路

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;
    }
};

 

posted @ 2019-06-12 16:57  你好哇傻小妞  阅读(111)  评论(0编辑  收藏  举报