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?

Example 1:

Input: 2, [[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: 2, [[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.

Note:

  1. The input prerequisites is a graph represented by a list of edges, not adjacency matrices. Read more about how a graph is represented.
  2. You may assume that there are no duplicate edges in the input prerequisites.
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. There are several ways to represent a graph. For example, the input prerequisites is a graph represented by a list of edges. Is this graph representation appropriate?
  3. Topological Sort via DFS - A great video tutorial (21 minutes) on Coursera explaining the basic concepts of Topological Sort.
  4. Topological sort could also be done via BFS.

这道课程清单的问题对于我们学生来说应该不陌生,因为在选课的时候经常会遇到想选某一门课程,发现选它之前必须先上了哪些课程,这道题给了很多提示,第一条就告诉了这道题的本质就是在有向图中检测环。 LeetCode 中关于图的题很少,有向图的仅此一道,还有一道关于无向图的题是 Clone Graph。个人认为图这种数据结构相比于树啊,链表啊什么的要更为复杂一些,尤其是有向图,很麻烦。第二条提示是在讲如何来表示一个有向图,可以用边来表示,边是由两个端点组成的,用两个点来表示边。第三第四条提示揭示了此题有两种解法,DFS 和 BFS 都可以解此题。先来看 BFS 的解法,定义二维数组 graph 来表示这个有向图,一维数组 in 来表示每个顶点的入度。开始先根据输入来建立这个有向图,并将入度数组也初始化好。然后定义一个 queue 变量,将所有入度为0的点放入队列中,然后开始遍历队列,从 graph 里遍历其连接的点,每到达一个新节点,将其入度减一,如果此时该点入度为0,则放入队列末尾。直到遍历完队列中所有的值,若此时还有节点的入度不为0,则说明环存在,返回 false,反之则返回 true。代码如下:

解法一:

class Solution {
public:
bool canFinish(int numCourses, vector<vector<int>>& prerequisites) {
vector<vector<int>> graph(numCourses, vector<int>());
vector<int> in(numCourses);
for (auto a : prerequisites) {
graph[a[]].push_back(a[]);
++in[a[]];
}
queue<int> q;
for (int i = ; i < numCourses; ++i) {
if (in[i] == ) q.push(i);
}
while (!q.empty()) {
int t = q.front(); q.pop();
for (auto a : graph[t]) {
--in[a];
if (in[a] == ) q.push(a);
}
}
for (int i = ; i < numCourses; ++i) {
if (in[i] != ) return false;
}
return true;
}
};

下面来看 DFS 的解法,也需要建立有向图,还是用二维数组来建立,和 BFS 不同的是,像现在需要一个一维数组 visit 来记录访问状态,这里有三种状态,0表示还未访问过,1表示已经访问了,-1 表示有冲突。大体思路是,先建立好有向图,然后从第一个门课开始,找其可构成哪门课,暂时将当前课程标记为已访问,然后对新得到的课程调用 DFS 递归,直到出现新的课程已经访问过了,则返回 false,没有冲突的话返回 true,然后把标记为已访问的课程改为未访问。代码如下:

解法二:

class Solution {
public:
bool canFinish(int numCourses, vector<vector<int>>& prerequisites) {
vector<vector<int>> graph(numCourses, vector<int>());
vector<int> visit(numCourses);
for (auto a : prerequisites) {
graph[a[]].push_back(a[]);
}
for (int i = ; i < numCourses; ++i) {
if (!canFinishDFS(graph, visit, i)) return false;
}
return true;
}
bool canFinishDFS(vector<vector<int>>& graph, vector<int>& visit, int i) {
if (visit[i] == -) return false;
if (visit[i] == ) return true;
visit[i] = -;
for (auto a : graph[i]) {
if (!canFinishDFS(graph, visit, a)) return false;
}
visit[i] = ;
return true;
}
};

Github 同步地址:

https://github.com/grandyang/leetcode/issues/207

类似题目:

Minimum Height Trees

Course Schedule II

Course Schedule III

Graph Valid Tree

参考资料:

https://leetcode.com/problems/course-schedule/

https://leetcode.com/problems/course-schedule/discuss/58524/Java-DFS-and-BFS-solution

https://leetcode.com/problems/course-schedule/discuss/58516/Easy-BFS-Topological-sort-Java

https://leetcode.com/problems/course-schedule/discuss/162743/JavaC%2B%2BPython-BFS-Topological-Sorting-O(N-%2B-E)

LeetCode All in One 题目讲解汇总(持续更新中...)

[LeetCode] Course Schedule 课程清单的更多相关文章

  1. [LeetCode] 207. Course Schedule 课程清单

    There are a total of n courses you have to take, labeled from 0 to n-1. Some courses may have prereq ...

  2. [LeetCode] Course Schedule II 课程清单之二

    There are a total of n courses you have to take, labeled from 0 to n - 1. Some courses may have prer ...

  3. [LeetCode] Course Schedule III 课程清单之三

    There are n different online courses numbered from 1 to n. Each course has some duration(course leng ...

  4. [LeetCode] 210. Course Schedule II 课程清单之二

    There are a total of n courses you have to take, labeled from 0 to n-1. Some courses may have prereq ...

  5. [LeetCode] 207. Course Schedule 课程安排

    There are a total of n courses you have to take, labeled from 0 to n - 1. Some courses may have prer ...

  6. 【LeetCode】1462. 课程安排 IV Course Schedule IV (Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 DFS 日期 题目地址:https://leetcod ...

  7. LeetCode Course Schedule II

    原题链接在这里:https://leetcode.com/problems/course-schedule-ii/ 题目: There are a total of n courses you hav ...

  8. [LeetCode] Course Schedule I (207) & II (210) 解题思路

    207. Course Schedule There are a total of n courses you have to take, labeled from 0 to n - 1. Some ...

  9. LeetCode - Course Schedule 解题报告

    以前从来没有写过解题报告,只是看到大肥羊河delta写过不少.最近想把写博客的节奏给带起来,所以就挑一个比较容易的题目练练手. 原题链接 https://leetcode.com/problems/c ...

随机推荐

  1. 解决Asp.net Mvc中使用异步的时候HttpContext.Current为null的方法

    在项目中使用异步(async await)的时候发现一个现象,HttpContext.Current为null,导致一系列的问题. 上网查了一些资料后找到了一个对象: System.Threading ...

  2. JavaScript易错知识点整理

    前言 本文是我学习JavaScript过程中收集与整理的一些易错知识点,将分别从变量作用域,类型比较,this指向,函数参数,闭包问题及对象拷贝与赋值这6个方面进行由浅入深的介绍和讲解,其中也涉及了一 ...

  3. 使用C#,轻松发邮件之QQ邮箱

    参考来源 http://www.cnblogs.com/youring2/archive/2008/11/29/1343911.html

  4. 移动端API接口优化的术和结果

    最近一直在忙工作的事情,所以文章写得有些少. 有3-5篇文章都是写到一半然后被别的事情给打断了,所以,我得找个时间好好补补. 最近一直在关注移动端接口API的可用性问题,在移动时代这个做这个优化能产生 ...

  5. 【python常用函数1】

    ## 1 ##获取输入值 a = raw_input("请输入:") if a == str(1): print "success" else: print & ...

  6. 【转译】加入ZigBee联盟,共画物联网的未来

    Zigbee联盟是物联网全球革命的领导者,创造了随心控制的时代.Zigbee简化了无线产品的整合.加快了市场化,同时让那些希望引入高能效的无线控制的厂商,降低了成本和风险.我们的联盟成员在开放的全球环 ...

  7. 数据结构:堆排序 (python版) 小顶堆实现从大到小排序 | 大顶堆实现从小到大排序

    #!/usr/bin/env python # -*- coding:utf-8 -*- ''' Author: Minion-Xu 小堆序实现从大到小排序,大堆序实现从小到大排序 重点的地方:小堆序 ...

  8. windows 7下React Native环境配置

    React Native 是 Facebook 推出的一个用 Java 语言就能同时编写 ios,android,以及后台的一项技术,它可以做到实时热更新 .FaceBook 也号称这们技术是 “Le ...

  9. Web Worker javascript多线程编程(一)

    什么是Web Worker? web worker 是运行在后台的 JavaScript,不占用浏览器自身线程,独立于其他脚本,可以提高应用的总体性能,并且提升用户体验. 一般来说Javascript ...

  10. Scala 包

    包的绝对地址_root_.开始 如_root_.scala.collection.mutable.ArrayBuffer