课程表 (leetcode)
现在你总共有 n 门课需要选,记为 0 到 n-1。
在选修某些课程之前需要一些先修课程。 例如,想要学习课程 0 ,你需要先完成课程 1 ,我们用一个匹配来表示他们: [0,1]
给定课程总量以及它们的先决条件,返回你为了学完所有课程所安排的学习顺序。
可能会有多个正确的顺序,你只要返回一种就可以了。如果不可能完成所有课程,返回一个空数组。
示例 1:
输入: 2, [[1,0]]
输出: [0,1]
解释: 总共有 2 门课程。要学习课程 1,你需要先完成课程 0。因此,正确的课程顺序为 [0,1] 。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/course-schedule-ii
本题实则上就是根据给定的二维数组建立图然后判断是否存在拓扑排序。如果图存在环,那么课程安排失败。如果安排成功,那么给出一个可行的课程顺序。
解答方案:
我们可以采用深度优先或者广度优先的方式进行搜索解答:
深度优先方式代码如下:
class Solution {List<List<Integer>> edges;//相当于采用邻接表的方式存储有向边int[] res;//表示的是结果数组,即安排的一种可行的顺序(拓扑排序)//我们需要的是从开始到最后的一种可行的安排,但是采用深度优先的方式的话,是等待其节点回溯的时候才会加入res中int count;int[] vis;//表示的是节点当前的状态,0表示为访问,1表示访问中(如果对某节点设置为1以后再次出现状态为1说明产生了环boolean existRound;//判断是否存在环的标志public int[] findOrder(int numCourses, int[][] prerequisites) {//采用深度优先的搜索方式//由于n门课是从0到n-1编号,故可以采用含有n个节点的邻接表实现图的存储//在java中用List<List<Integer>> 很容易实现邻接表edges = new ArrayList<List<Integer>>();for(int i = 0; i < numCourses; i++){edges.add(new ArrayList<Integer>());}for(int[] row : prerequisites){edges.get(row[1]).add(row[0]);//由于给定的[0, 1]表示的是课程1需要在课程0之前,所以需要的是1->0的边}count = numCourses - 1;vis = new int[numCourses];res = new int[numCourses];//由于出现的图可能不是一次深度优先就可以完成的,所以需要对每个节点均进行判断是否访问过了for(int i = 0; i < numCourses; i++){if(vis[i] == 0 && !existRound){dfs(i);}}if(existRound) return new int[]{};return res;}public void dfs(int i){//以当前i节点开始进行深度优先遍历vis[i] = 1;//置标志为搜索中。// for(int j = 0; j < edges.get(i).size(); j++){// int k = edges.get(i).get(j);// if(vis[k] == 0){// dfs(k);// if(existRound) return;// }else if(vis[k] == 1){// existRound = true;// return;// }// }//该循环与上面的作用是一样的,for(int j : edges.get(i)){if(vis[j] == 0){//如果i的临界点还没有访问过,则继续访问dfs(j);}else if(vis[j] == 1){//如果i的其中一个邻接点处于搜索中的状态,说明产生了环existRound = true;return ;}if(existRound) return;}vis[i] = 2;//表示i结点访问完成,设置其状态为2res[count--] = i;//存储结果}
}
广度优先方式的代码如下:
class Solution {List<List<Integer>> edges;//相当于采用邻接表的方式存储有向边int[] res;//表示的是结果数组,即安排的一种可行的顺序(拓扑排序),相对于深度优先,广度优先更加的直观,其解决方法是正向的int[] indulg;//存储节点的入度public int[] findOrder(int numCourses, int[][] prerequisites) {//采用广度优先的搜索方式,该方式需要存储每个节点的入度//由于n门课是从0到n-1编号,故可以采用含有n个节点的邻接表实现图的存储//在java中用List<List<Integer>> 很容易实现邻接表edges = new ArrayList<List<Integer>>();for(int i = 0; i < numCourses; i++){edges.add(new ArrayList<Integer>());}indulg = new int[numCourses];for(int[] row : prerequisites){edges.get(row[1]).add(row[0]);//由于给定的[0, 1]表示的是课程1需要在课程0之前,所以需要的是1->0的边++indulg[row[0]];}res = new int[numCourses];Queue<Integer> qu = new LinkedList<Integer>();//由于出现的图可能不是一次广度优先就可以完成的,所以需要对每个入度为0的节点入队for(int i = 0; i < numCourses; i++){if(indulg[i] == 0){qu.offer(i);}}int count = 0;while(!qu.isEmpty()){//队列中的节点全部是入度为0的节点int u = qu.poll();res[count++] = u;//u便是当前可以安排的课程for(int v : edges.get(u)){--indulg[v]; //这里需要先把入度减1,因为从u到v的边的入度计算需要减去if(indulg[v] == 0){//满足入队的条件qu.offer(v);}}} if(count != numCourses) return new int[]{}; return res;}
}
课程表 (leetcode)相关推荐
- LeetCode刷题实战216:组合总和 III
算法的重要性,我就不多说了吧,想去大厂,就必须要经过基础知识和业务逻辑面试+算法面试.所以,为了提高大家的算法能力,这个公众号后续每天带大家做一道算法题,题目就从LeetCode上面选 ! 今天和大家 ...
- LeetCode1-620题汇总,希望对你有点帮助!
时间很快,公众号发布的LeetCode题目,已经达到620道题了.今天把发布的1-620篇LeetCode文章整理一下,平时文章都放在比较末尾,阅读量都不高,相信很多人都没看过,如果对于算法感兴趣的, ...
- LeetCode1-580题汇总,希望对你有点帮助!
时间很快,公众号发布的LeetCode题目,已经达到560道题了.今天把发布的1-560篇LeetCode文章整理一下,平时文章都放在比较末尾,阅读量都不高,相信很多人都没看过,如果对于算法感兴趣的, ...
- LeetCode1-560题汇总,希望对你有点帮助!
时间很快,公众号发布的LeetCode题目,已经达到560道题了.今天把发布的1-560篇LeetCode文章整理一下,平时文章都放在比较末尾,阅读量都不高,相信很多人都没看过,如果对于算法感兴趣的, ...
- LeetCode1-540题汇总,希望对你有点帮助!
时间很快,公众号发布的LeetCode题目,已经达到520道题了.今天把发布的1-520篇LeetCode文章整理一下,平时文章都放在比较末尾,阅读量都不高,相信很多人都没看过,如果对于算法感兴趣的, ...
- LeetCode1-500题汇总,希望对你有点帮助!
时间很快,公众号发布的LeetCode题目,已经达到500道题了.今天把发布的1-500篇LeetCode文章整理一下,平时文章都放在比较末尾,阅读量都不高,相信很多人都没看过,如果对于算法感兴趣的, ...
- LeetCode1-480题汇总,希望对你有点帮助!
时间很快,公众号发布的LeetCode题目,已经达到480道题了.今天把发布的1-480篇LeetCode文章整理一下,平时文章都放在比较末尾,阅读量都不高,相信很多人都没看过,如果对于算法感兴趣的, ...
- LeetCode1-440题汇总,希望对你有点帮助!
时间很快,公众号发布的LeetCode题目,已经达到440道题了.今天把发布的1-440篇LeetCode文章整理一下,平时文章都放在比较末尾,阅读量都不高,相信很多人都没看过,如果对于算法感兴趣的, ...
- LeetCode1-400题汇总,希望对你有点帮助!
时间很快,公众号发布的LeetCode题目,已经达到400道题了.今天把发布的1-400篇LeetCode文章整理一下,平时文章都放在比较末尾,阅读量都不高,相信很多人都没看过,如果对于算法感兴趣的, ...
最新文章
- ACMMM2017 | 电子科大斩获最佳论文!中科院自动化所多媒体计算组获得IEEE期刊最佳论文!
- [UWP]在应用开发中安全使用文件资源
- C++通过GSoap访问webService
- 时间序列模型(ARIMA模型)
- 算法导论22章 基本图算法习题
- c语言字符串截取_笔记 | 自学Python 05:数据类型之字符串
- 【计蒜客 - 蓝桥训练】阶乘位数(数学,对数运算,求阶乘位数)
- Windows 2003安全事件ID分析(1)
- pcjome新闻图片替换效果
- 【java】java 分支预测 Java处理排序后的数组比没有排序的快
- 基于MVC模式Struts框架研究
- 多线程(thread)+进程(Process)
- PS使用:利用PS制作旋转水晶球gif图
- vue 针试打印机实现
- k2运营商服务器无响应,【求救】K2提示“等待PPP客户端连接”拨号失败
- 知网不能下载PDF?CAJ格式太鸡肋?
- linux内核的学习方法
- android计算器如何保存记录,计算器历史记录怎么看
- Git学习笔记(二)——Git的分支管理、储藏和标签
- X86与ARM平台下的参数传递机制