[LeetCode] 207. Course Schedule

题:https://leetcode.com/problems/course-schedule/description/

题目

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?

Example 1:

Input: 2, [[1,0]] 
Output: true
Explanation: There are a total of 2 courses to take. 
             To take course 1 you should have finished course 0. So it is possible.

Example 2:

Input: 2, [[1,0],[0,1]]
Output: false
Explanation: There are a total of 2 courses to take. 
             To take course 1 you should have finished course 0, and to take course 0 you should
             also have finished course 1. So it is impossible.

Note:

  • The input prerequisites is a graph represented by a list of edges, not adjacency matrices. Read more about how a graph is represented.
  • You may assume that there are no duplicate edges in the input prerequisites.

题目大意

判断给定的 图是否 存在环。

思路

方法一 拓扑排序

找到图中入度为1的节点,删去 该点以及该点的出边。
重复上述操作。
若所有点 都 度为1,那么该图为五环图。

class Solution {
    public boolean canFinish(int numCourses, int[][] prerequisites) {
        List<Integer>[] graph = new List[numCourses];
        for(int i = 0 ;i < numCourses;i++){
            graph[i] = new ArrayList<>();
        }
        int[] inDegree = new int[numCourses];
        for(int i = 0; i < prerequisites.length;i++){
            graph[prerequisites[i][1]].add(prerequisites[i][0]);
            inDegree[prerequisites[i][0]]++;
        }
        Queue<Integer>  quque = new LinkedList<>();

        for(int i = 0; i < inDegree.length;i++){
            if(inDegree[i] == 0)
                quque.offer(i);
        }
        while(!quque.isEmpty()){
            int curNode = quque.poll();
            for(int i = 0;i < graph[curNode].size();i++)
                if(--inDegree[graph[curNode].get(i)] == 0)
                    quque.offer(graph[curNode].get(i));
        }
        for(int i = 0;i < inDegree.length ; i++)
            if(inDegree[i] != 0 )
                return false;
        return true;
    }
}

上述方法的 小改进,统计 删除的点。若删除的点 等于 图中所有的点,那么该图为无环图。


方法二 DFS 探索法

从一个点 DFS探索,若本次 探索过程中,发现当前点已经被探索了。那么该图必有环。
若当前点,在以前的探索过程中已经探索了,那么 探索的为同一个连通分量,该分量比没有 环。

用BDFS ,将localMarked 标识为 当前的 探索的点。

class Solution {
    public boolean canFinish(int numCourses, int[][] prerequisites) {
        List<Integer>[] graph = new List[numCourses];
        for(int i = 0;i<graph.length;i++)
            graph[i] = new ArrayList<>();
        for(int i = 0;i<prerequisites.length;i++){
            graph[prerequisites[i][1]].add(prerequisites[i][0]);
        }
        boolean [] globalMarked = new boolean[numCourses];
        boolean [] localMarked = new boolean[numCourses];
        for(int i = 0 ;i < numCourses;i++)
            if(hasCycle(globalMarked,localMarked,graph,i))
               return false;
        return true;
    }
    public boolean hasCycle(boolean[] globalMarked,boolean[] localMarked,List<Integer>[] graph,int curNode){
        if(localMarked[curNode])
            return true;
        if(globalMarked[curNode])
            return false;
        localMarked[curNode] = true;
        globalMarked[curNode] = true;
        for(int nextNode:graph[curNode])
            if(hasCycle(globalMarked,localMarked,graph,nextNode))
                return true;
        localMarked[curNode] = false;
        return false;
    }
}

猜你喜欢

转载自blog.csdn.net/u013383813/article/details/83144448