zoukankan      html  css  js  c++  java
  • 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?
    
    For example:
    
    2, [[1,0]]
    There are a total of 2 courses to take. To take course 1 you should have finished course 0. So it is possible.
    
    2, [[1,0],[0,1]]
    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.
    click to show more hints.
    
    Hints:
    This problem is equivalent to finding if a cycle exists in a directed graph. If a cycle exists, no topological ordering exists and therefore it will be impossible to take all courses.
    Topological Sort via DFS - A great video tutorial (21 minutes) on Coursera explaining the basic concepts of Topological Sort.
    Topological sort could also be done via BFS.

    思路

    先修课程是拓扑排序的经典应用, 这里相当于找有向图是否有环, 如果有环的话拓扑排序能遍历到的节点将少于图的节点. 这里我们建立一个图, 用一个数组记录每个节点的入度. 对图进行拓扑排序

    复杂度

    时间O(V+E) 空间 O(V)

    public boolean canFinish(int numCourses, int[][] prerequisites) {
        if (prerequisites == null || prerequisites.length == 0 || prerequisites[0].length == 0) {
            return true;
        }
        //记录入度
        int[] indgree = new int[numCourses];
        //记录有向图的指向节点
        ArrayList[] graph = new ArrayList[numCourses];
        for (int i = 0; i < numCourses; i++) {
            graph[i] = new ArrayList<Integer>();
        }
        //写入有向图的next节点
        for (int i = 0; i < prerequisites.length; i++) {
            graph[prerequisites[i][1]].add(prerequisites[i][0]);
            indgree[prerequisites[i][0]]++;
        }
        Queue<Integer> queue = new LinkedList<Integer>();
        for(int i = 0; i < indgree.length; i++){
            if(indgree[i] == 0){
                queue.add(i);
            }
        }
        int count = 0;
        while (!queue.isEmpty()) {
            int cur = queue.poll();
            count++;
            ArrayList<Integer> list = graph[cur];
            for (Integer tem : list) {
                indgree[tem]--;
                if (indgree[tem] == 0) {
                    queue.offer(tem);
                }
            }
        }
        return count == numCourses;
    }
    

    有向图: 入度和边, 用什么容器, 怎么生成图, 根据什么入队, 出队后怎么遍历其他的边, 并判断入队, 

    题意的分解:拓扑排序,BFS

    难点--边的生成容器: 

     //记录有向图的指向节点
        ArrayList[] graph = new ArrayList[numCourses];
        for (int i = 0; i < numCourses; i++) {
            graph[i] = new ArrayList<Integer>();
        }

     生成图的容器 要有且明确是谁的:

    1键值对, 且值是容器比如ArrayList[], hashmap<键, ArrayList<jian>())

    2入度: int[], Arraylist.size()? 

  • 相关阅读:
    Python NLP入门教程
    一个月入门Python爬虫,轻松爬取大规模数据
    Python爬虫实战案例:爬取爱奇艺VIP视频
    探索Python F-strings是如何工作
    Ruby 和 Python 分析器是如何工作的?
    超级干货,python常用函数大总结
    Python 开发者的 6 个必备库,你都了解吗?
    神经网络中 BP 算法的原理与 Python 实现源码解析
    新手程序员必学的代码编程技巧
    零基础小白怎么用Python做表格?
  • 原文地址:https://www.cnblogs.com/apanda009/p/7225909.html
Copyright © 2011-2022 走看看