zoukankan      html  css  js  c++  java
  • Leetcode: 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.

    The hint provided by leetcode is:

    Hints:

    1. 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.
    2. Topological Sort via DFS - A great video tutorial (21 minutes) on Coursera explaining the basic concepts of Topological Sort.
    3. Topological sort could also be done via BFS.

    BFS: 

    典型的拓扑排序。原理也很简单,在一个有向图中,每次找到一个没有前驱节点的节点(也就是入度为0的节点),然后把它指向其他节点的边都去掉,重复这个过程(BFS),直到所有节点已被找到,或者没有符合条件的节点(如果图中有环存在)。

    回顾一下图的三种表示方式:边表示法(即题目中表示方法),邻接表法,邻接矩阵。用邻接表存储图比较方便寻找入度为0的节点。

     1 public class Solution {
     2     public boolean canFinish(int numCourses, int[][] prerequisites) {
     3         ArrayList<Integer>[] graph = new ArrayList[numCourses];
     4         int[] indegree = new int[numCourses];
     5         
     6         for (int i=0; i<numCourses; i++) {
     7             graph[i] = new ArrayList<Integer>();
     8         }
     9         
    10         for (int[] each : prerequisites) {
    11             graph[each[0]].add(each[1]);
    12             indegree[each[1]]++;
    13         }
    14         
    15         Queue<Integer> queue = new LinkedList<Integer>();
    16         for (int i=0; i<indegree.length; i++) {
    17             if (indegree[i] == 0) {
    18                 queue.offer(i);
    19             }
    20         }
    21         
    22         int count = 0;
    23         while (!queue.isEmpty()) {
    24             int cur = (int)queue.poll();
    25             count++;
    26             
    27             for (int course : graph[cur]) {
    28                 indegree[course]--;
    29                 if (indegree[course] == 0) {
    30                     queue.offer(course);
    31                 }
    32             }
    33         }
    34         return count == numCourses;
    35     }
    36 }

    Better solution: Adjacent Matrix

     1 public boolean canFinish(int numCourses, int[][] prerequisites) {
     2     int[][] matrix = new int[numCourses][numCourses]; // i -> j
     3     int[] indegree = new int[numCourses];
     4     
     5     for (int i=0; i<prerequisites.length; i++) {
     6         int ready = prerequisites[i][0];
     7         int pre = prerequisites[i][1];
     8         if (matrix[pre][ready] == 0)
     9             indegree[ready]++; //duplicate case
    10         matrix[pre][ready] = 1;
    11     }
    12     
    13     int count = 0;
    14     Queue<Integer> queue = new LinkedList();
    15     for (int i=0; i<indegree.length; i++) {
    16         if (indegree[i] == 0) queue.offer(i);
    17     }
    18     while (!queue.isEmpty()) {
    19         int course = queue.poll();
    20         count++;
    21         for (int i=0; i<numCourses; i++) {
    22             if (matrix[course][i] != 0) {
    23                 if (--indegree[i] == 0)
    24                     queue.offer(i);
    25             }
    26         }
    27     }
    28     return count == numCourses;
  • 相关阅读:
    近期计划安排
    线段树+离散化+染色
    矩阵快速幂(共轭函数两种递推式)
    树状数组求区间最值和单点更新
    矩阵快速幂(共轭函数)
    树状数组之区间更新与查询
    Python List min()方法
    Python List max()方法
    Python List len()方法
    Python List cmp()方法
  • 原文地址:https://www.cnblogs.com/EdwardLiu/p/5050550.html
Copyright © 2011-2022 走看看