zoukankan      html  css  js  c++  java
  • LeetCode:课程表【207】

    LeetCode:课程表【207】

    题目描述

    现在你总共有 n 门课需要选,记为 0 到 n-1

    在选修某些课程之前需要一些先修课程。 例如,想要学习课程 0 ,你需要先完成课程 1 ,我们用一个匹配来表示他们: [0,1]

    给定课程总量以及它们的先决条件,判断是否可能完成所有课程的学习?

    示例 1:

    输入: 2, [[1,0]] 
    输出: true
    解释: 总共有 2 门课程。学习课程 1 之前,你需要完成课程 0。所以这是可能的。

    示例 2:

    输入: 2, [[1,0],[0,1]]
    输出: false
    解释: 总共有 2 门课程。学习课程 1 之前,你需要先完成​课程 0;并且学习课程 0 之前,你还应先完成课程 1。这是不可能的。

    说明:

    1. 输入的先决条件是由边缘列表表示的图形,而不是邻接矩阵。详情请参见图的表示法
    2. 你可以假定输入的先决条件中没有重复的边。

    题目分析

      我们做这道题之前,需要先理解一个概念,就是拓扑排序。可以先参看这篇文章算法:拓扑排序

      如果我们已经理解了拓扑排序,那么这道题相对来说就比较简单了。这道题的核心点是判断有向图是否有环

      存在下面这种情况的就返回FALSE:

      

      拓扑排序算法如何判断是否有环?

        如上图的右半部分所示,首先黑色是节点的默认颜色,我们把访问到的节点标记为红色,在遇到出度为0的第一个节点时,我们将它标记为蓝色,最后所有的节点都会被染成蓝色,说明这是一个合法的拓扑图。

        但是,在有环路的情况下,无论如何都无法到达出度为0的节点,当所有的黑色节点都变成红色后,还没有出现一个蓝色,那说明就是有环。

        所以,我们把黑色表示为0,蓝色表示为1,红色表示为2,遇到黑色节点很正常,遇到蓝色节点也很正常(两者都是正常的拓扑排序环节),但是当我们遇到红色节点的时候说明遇到环路

        好了,说到这里,我觉得已经很清楚了,实现细节请看代码。

    Java题解

    class Solution {
         public boolean canFinish(int numCourses, int[][] prerequisites) {
            ArrayList<ArrayList<Integer>> graph = new ArrayList<>();
            for(int i=0;i<numCourses;i++)
                graph.add(new ArrayList<>());
            for(int i=0;i<prerequisites.length;i++)
            {
                int course = prerequisites[i][0];
                int pcourse = prerequisites[i][1];
                graph.get(course).add(pcourse);
            }
            int[] visited = new int[numCourses];
            for(int i=0;i<numCourses;i++)
                if(DFS(i,graph,visited))
                    return false;
            return true;
        }
    
        public boolean DFS(int curr,ArrayList<ArrayList<Integer>> graph,int[] visited)
        {
            //递归结束条件
            if(visited[curr]==1)//这个节点已经被访问
                return true;
            if(visited[curr]==2)//这个节点没有被访问
                return false;
            
            //业务逻辑处理
            visited[curr]=1;//表示正在访问
            for(int id:graph.get(curr))
                if(DFS(id,graph,visited))
                    return true;
            visited[curr]=2;//表示已经访问
            return false;
        }
    }
  • 相关阅读:
    web 服务器
    mysql
    Vue学习之路第二十篇:Vue生命周期函数-组件创建期间的4个钩子函数
    Vue学习之路第十九篇:按键修饰符的使用
    Vue学习之路第十八篇:私有过滤器的使用
    Vue学习之路第十七篇:全局过滤器的使用
    Vue学习之路第十六篇:车型列表的添加、删除与检索项目
    Vue学习之路第十五篇:v-if和v-show指令
    Vue学习之路第十四篇:v-for指令中key的使用注意事项
    Vue学习之路第十三篇:v-for指令
  • 原文地址:https://www.cnblogs.com/MrSaver/p/9996941.html
Copyright © 2011-2022 走看看