zoukankan      html  css  js  c++  java
  • [LeetCode] 207. Course Schedule

    There are a total of numCourses courses you have to take, labeled from 0 to numCourses-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?

    Example 1:

    Input: numCourses = 2, prerequisites = [[1,0]]
    Output: true
    Explanation: There are a total of 2 courses to take. 
                 To take course 1 you should have finished course 0. So it is possible.
    

    Example 2:

    Input: numCourses = 2, prerequisites = [[1,0],[0,1]]
    Output: false
    Explanation: 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.
    

    Constraints:

    • 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.
    • 1 <= numCourses <= 10^5

    课程表。

    你这个学期必须选修 numCourses 门课程,记为 0 到 numCourses - 1 。

    在选修某些课程之前需要一些先修课程。 先修课程按数组 prerequisites 给出,其中 prerequisites[i] = [ai, bi] ,表示如果要学习课程 ai 则 必须 先学习课程  bi 。

    例如,先修课程对 [0, 1] 表示:想要学习课程 0 ,你需要先完成课程 1 。
    请你判断是否可能完成所有课程的学习?如果可以,返回 true ;否则,返回 false 。

    来源:力扣(LeetCode)
    链接:https://leetcode-cn.com/problems/course-schedule
    著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

    典型的拓扑排序题目。拓扑排序又称之为有向无环图(DAG)。拓扑排序的定义在这里就不赘述了。这个题目有多种做法,此处我解释一下BFS的思路。首先为所有课程创建一个入度表indegree,遍历所有的课程。所有课程的prerequisites都以一个 pair[0, 1] 表示(0的先修课程是1),所以遍历所有的 pair[0],建立所有课程的入度表。此时再遍历这个入度表,将入度表中所有为0(没有先修课程)的元素加入一个队列。遍历这个队列,每弹出一个元素 cur,就减去一门课 res--,去 prerequisites 中看是否有其他课程 pair[0] 的先修课程是 cur,若有,则在入度表里面找到这个 pair[0] 并减1。如果这个 pair[0] 也被减到入度为0了,则把他加入队列继续查找,看这个 pair[0] 是否是别的课的先修课。最后会跳出while循环,跳出的时候判断是不是所有课程 res 都遍历完了。

    时间O(V + E)

    空间O(n)

    Java实现

     1 class Solution {
     2     public boolean canFinish(int numCourses, int[][] prerequisites) {
     3         int[] indegree = new int[numCourses];
     4         int res = numCourses;
     5         for (int[] pair : prerequisites) {
     6             indegree[pair[0]]++;
     7         }
     8 
     9         // 把所有入度为0的节点加入队列
    10         // 入度为0说明没有先修课程
    11         Queue<Integer> queue = new LinkedList<>();
    12         for (int i = 0; i < indegree.length; i++) {
    13             if (indegree[i] == 0) {
    14                 queue.offer(i);
    15             }
    16         }
    17 
    18         // 遍历所有入度为0的课程
    19         while (!queue.isEmpty()) {
    20             int pre = queue.poll();
    21             res--;
    22             // 看是否有其他课程的先修课程是pre
    23             for (int[] pair : prerequisites) {
    24                 if (pair[1] == pre) {
    25                     indegree[pair[0]]--;
    26                     if (indegree[pair[0]] == 0) {
    27                         queue.offer(pair[0]);
    28                     }
    29                 }
    30             }
    31         }
    32         return res == 0;
    33     }
    34 }

    相关题目

    207. Course Schedule

    210. Course Schedule II

    269. Alien Dictionary

    310. Minimum Height Trees

    953. Verifying an Alien Dictionary

    LeetCode 题目总结

  • 相关阅读:
    Python全栈之机器学习参考笔记
    每个Kaggle冠军的获胜法门:揭秘Python中的模型集成
    logback配置文件
    浅谈Spring中的IOC容器
    JavaWeb三大组件之Servlet
    JavaWeb三大组件之Filter
    常用执行计划操作符
    Linux环境下Redis集群实践
    SQL事物隔离级别
    任务调度框架-Quartz.Net
  • 原文地址:https://www.cnblogs.com/cnoodle/p/12467256.html
Copyright © 2011-2022 走看看