[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?
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:
- 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.
- 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.
- 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?
- 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.
这道课程清单的问题对于我们学生来说应该不陌生,因为在选课的时候经常会遇到想选某一门课程,发现选它之前必须先上了哪些课程,这道题给了很多提示,第一条就告诉了这道题的本质就是在有向图中检测环。 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
类似题目:
参考资料:
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
LeetCode All in One 题目讲解汇总(持续更新中...)
[LeetCode] Course Schedule 课程清单的更多相关文章
- [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 ...
- [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 ...
- [LeetCode] Course Schedule III 课程清单之三
There are n different online courses numbered from 1 to n. Each course has some duration(course leng ...
- [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 ...
- [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 ...
- 【LeetCode】1462. 课程安排 IV Course Schedule IV (Python)
作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 DFS 日期 题目地址:https://leetcod ...
- LeetCode Course Schedule II
原题链接在这里:https://leetcode.com/problems/course-schedule-ii/ 题目: There are a total of n courses you hav ...
- [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 ...
- LeetCode - Course Schedule 解题报告
以前从来没有写过解题报告,只是看到大肥羊河delta写过不少.最近想把写博客的节奏给带起来,所以就挑一个比较容易的题目练练手. 原题链接 https://leetcode.com/problems/c ...
随机推荐
- 压力测试之badboy和Jmeter的简单使用方法
文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/ 1.背景 所谓压力测试是指,通过确定一个系统的瓶颈或者不能接收的性能点, ...
- (福利)分享一个用android编写的简单的APP——爱吖天气
这是本人随便编写的一个天气的APP,超级简单. 项目已同步至:https://github.com/nanchen2251/AiYaWeatherDemo 基本实现了天气查看,闪屏引导,天气基本信息, ...
- js实现StringBuffer
实现 function StringBuffer() { this.__strings__ = []; }; StringBuffer.prototype.Append = function (str ...
- 使用h5的history改善ajax列表请求体验
信息比较丰富的网站通常会以分页显示,在点“下一页”时,很多网站都采用了动态请求的方式,避免页面刷新.虽然大家都是ajax,但是从一些小的细节还是 可以区分优劣.一个小的细节是能否支持浏览器“后退”和“ ...
- 基于Metronic的Bootstrap开发框架经验总结(14)--条码和二维码的生成及打印处理
在很多项目里面,对条形码和二维码的生成和打印也是一种很常见的操作,在Web项目里面,我们可以利用JS生成条形码和二维码的组件有很多.本文引入两个比较广泛使用的JS组件,用来处理条形码和二维码的生成处理 ...
- Maven环境配置
1.下载Maven: 下载地址:http://maven.apache.org/ 2..安装 Maven 如果需要使用到 Maven ,必须首先安装 Maven , Maven 的下载地址在 Apac ...
- jquery遍历table获取td单元格的值
$("#grd").find("tr").each(function () { //第二列单元格的值eq(索引) alert($(this).children( ...
- Linux安装jdk
查看Java的版本命令:java -version 查看java版本的方法是:运行--->cmd,输入java –version.注意: java命令后是有个空格的,-version表示参数而已 ...
- CSS常用渐变
边框渐变: border-image: -webkit-linear-gradient( red , blue) 30 30; border-image: -moz-linear-gradient( ...
- 移动Web触摸与运动解决方案AlloyTouch开源啦
传送门 Github地址:https://github.com/AlloyTeam/AlloyTouch 简介 AlloyTouch的本质是运动一个数字,把数字的物理变化映射到你想映射的任何属性上.所 ...