美文网首页程序员
Leetcode 存档点(1)-- 课程表II

Leetcode 存档点(1)-- 课程表II

作者: kolibreath | 来源:发表于2020-05-25 17:53 被阅读0次

课程表II

这道题的基本思想是和拓扑排序相关联的,属于一个图的问题

图的存储结构

邻接矩阵表示法

邻接矩阵表示法

邻接表表示法

邻接表表示法

拓扑排序

拓扑排序的过程就是在有向无环图中选择入度为0的节点,删除由它作为起点的邻边,重复这个过程,直到这个所有点都被输出。

BFS进行拓扑排序

初始 删除0 删除1 删除2

按照出度和入度的变化情况和通过队列的方式,很容易计算出一个拓扑排序的序列。这道题可以使用这样的BFS的方法进行拓扑排序,如果发现到最后,整个图没有遍历完成,并且没法输出节点,这时候说明出现了环,整个课程表问题没有办法解决。

DFS进行拓扑排序

使用DFS进行拓扑排序和图的排序方法大体相同,都主要使用的是深度优先搜索+visited数组记录排序的情况。但是由于visited数组中只有访问和未访问两个状态,而这道题是为了发现是否有环存在,所以要分成三个状态:

  1. 未访问- >访问此节点,标记为访问中,并且将节点将入栈中,弹出之后标记成已访问。
  2. 已访问 -> 跳过这个节点,访问下一个
  3. 访问中 -> 存在环,结束整个遍历搜索

在我们要完成这道题的编码的时候,我们选择邻接表是比较合适的。
代码如下:

public class 课程表II {
    //https://leetcode-cn.com/problems/course-schedule-ii/
    //一道拓扑排序的问题
     class Solution {
        private ArrayList<ArrayList<Integer>> graph = new ArrayList<>();
        private int visited[] ;
        private int status[] = {0,1,2};

        //如果遍历过程中出现了环的情况
        private boolean invalid = false;
        private LinkedList<Integer> stack = new LinkedList<>();
        //主要的dfs算法,使用栈保存迭代的情况
        private void dfs(int index){
            visited[index] = status[1];
            ArrayList<Integer> connected = graph.get(index);
            for (Integer sub : connected){
                //如果是未搜索的状态 直接进行递归
                if(visited[sub] == status[0]){
                    dfs(sub);
                    if(invalid) return;
                }
                //如果是搜索中的状态 出现了环路(最简单的情况是衔尾蛇)
                if(visited[sub] == status[1]){
                    invalid = true;
                    return;
                }
            }
            visited[index] = status[2];
            stack.add(index);
        }

        public int[] findOrder(int numCourses, int[][] prerequisites) {
            visited = new int[numCourses];
            //初始化graph
            for (int i = 0; i< numCourses ; i++) {
                graph.add(new ArrayList<>());
                visited[i] = 0;
            }

            for (int i = 0; i < prerequisites.length ; i++) {
                graph.get(prerequisites[i][1]).add(prerequisites[i][0]);
            }
            //遍历每一个起
            for (int i = 0; i < numCourses; i++) {
                if(visited[i]== status[2])
                    continue;
                dfs(i);
            }

            if(invalid)
                return new int[0];

            int result[] = new int[numCourses];
            Collections.reverse(stack);
            for (int i = 0; i < stack.size(); i++) {
                result[i] = stack.get(i);
            }

            return result;
        }
    }

}

相关文章

网友评论

    本文标题:Leetcode 存档点(1)-- 课程表II

    本文链接:https://www.haomeiwen.com/subject/ryyyahtx.html