zoukankan      html  css  js  c++  java
  • Course Schedule 解答

    Question

    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.

    Solution 1 -- DFS

    This question can be transferred to judge whether the graph has cycle.

    There are two key points for this question.

    1. How to construct adjacency list according to edge lists? (Graph representation)

    Usually, we use ArrayList[] to represent adjacency list.

    2. How to use DFS to judge whether the graph has cycle. This solution can be further modified to implement topological sort.

    Time complexity O(|V| + |E|)

     1 public class Solution {
     2     public boolean canFinish(int numCourses, int[][] prerequisites) {
     3         if (prerequisites == null || prerequisites.length == 0)
     4             return true;
     5         // Construct adjacency list
     6         ArrayList<Integer>[] adjacencyList = new ArrayList[numCourses];
     7         for (int i = 0; i < numCourses; i++) {
     8             ArrayList<Integer> tmpList = new ArrayList<Integer>();
     9             tmpList.add(i);
    10             adjacencyList[i] = tmpList;
    11         }
    12         for (int i = 0; i < prerequisites.length; i++) {
    13             int[] currentPair = prerequisites[i];
    14             adjacencyList[currentPair[0]].add(currentPair[1]);
    15         }
    16         
    17         // DFS Because we need to judge whether the graph has cycle, we use three status for each node
    18         // 0 -> not start; 1 -> start dfs, but not complete; 2 -> complete dfs; 
    19         short[] used = new short[numCourses];
    20         for (int i = 0; i < numCourses; i++) {
    21             if (used[i] == 0) {
    22                 boolean result = dfs(adjacencyList, used, i);
    23                 if (!result)
    24                     return false;
    25             }
    26         }
    27         return true;
    28     }
    29     
    30     private boolean dfs(ArrayList<Integer>[] graph, short[] used, int i) {
    31         used[i] = 1;
    32         ArrayList<Integer> neighbor = graph[i];
    33         for (int j = 1; j < neighbor.size(); j++) {
    34             int index = neighbor.get(j);
    35             if (used[index] == 1)
    36                 return false;
    37             if (used[index] == 2)
    38                 continue;
    39             if (used[index] == 0) {
    40                 if (!dfs(graph, used, index))
    41                     return false;
    42             }
    43         }
    44         used[i] = 2;
    45         return true;
    46     }
    47     
    48 }

     Solution 2

    We adopt second way to implement topological sort.

    We maintain a queue to store vertices whose in-degree is 0. Time complexity O(|V| + |E|).

     1 public class Solution {
     2     public boolean canFinish(int numCourses, int[][] prerequisites) {
     3         if (prerequisites == null || prerequisites.length == 0)
     4             return true;
     5         // Construct adjacency list
     6         ArrayList<Integer>[] adjacencyList = new ArrayList[numCourses];
     7         for (int i = 0; i < numCourses; i++) {
     8             ArrayList<Integer> tmpList = new ArrayList<Integer>();
     9             tmpList.add(i);
    10             adjacencyList[i] = tmpList;
    11         }
    12         for (int i = 0; i < prerequisites.length; i++) {
    13             int[] currentPair = prerequisites[i];
    14             adjacencyList[currentPair[0]].add(currentPair[1]);
    15         }
    16         // Maintain a queue to store vertices with in-degree is 0
    17         Queue<Integer> queue = new LinkedList<Integer>();
    18         int[] inDegree = new int[numCourses];
    19         Arrays.fill(inDegree, 0);
    20         // Initialize in-degree array
    21         for (ArrayList<Integer> tmpList : adjacencyList) {
    22             int size = tmpList.size();
    23             for (int i = 1; i < size; i++)
    24                 inDegree[tmpList.get(i)]++;
    25         }
    26         // Initialize queue
    27         for (int i = 0; i < numCourses; i++) {
    28             if (inDegree[i] == 0)
    29                 queue.add(i);
    30         }
    31         if (queue.size() == 0)
    32             return false;
    33         int count = 0;
    34         while (queue.size() > 0) {
    35             int key = queue.remove();
    36             ArrayList<Integer> neighbor = adjacencyList[key];
    37             for (int i = 1; i < neighbor.size(); i++) {
    38                 int tmp = neighbor.get(i);
    39                 inDegree[tmp]--;
    40                 if (inDegree[tmp] == 0) {
    41                     queue.add(tmp);
    42                 }
    43             }
    44             count++;
    45         }
    46         return count == numCourses;
    47     }
    48 }
  • 相关阅读:
    Java Comparator和Comparabler的区别
    正则表达式全部符号解释
    Java使用reids,以及redis与shiro集成
    jQuery的select相关操作
    javascrit原生实现jquery的append()函数
    spring拦截器 实现应用之性能监控
    Gitlab完美安装【CentOS6.5安装gitlab-6.9.2】
    关于datepicker只显示年、月、日的设置
    spring aop 环绕通知around和其他通知的区别
    springMVC和spring各自扫描自己的注解不要相互混淆
  • 原文地址:https://www.cnblogs.com/ireneyanglan/p/4845384.html
Copyright © 2011-2022 走看看