现在你总共有 n 门课需要选,记为 0 到 n-1

在选修某些课程之前需要一些先修课程。 例如,想要学习课程 0 ,你需要先完成课程 1 ,我们用一个匹配来表示他们: [0,1]

给定课程总量以及它们的先决条件,判断是否可能完成所有课程的学习?

示例 1:

输入: 2, [[1,0]]
输出: true
解释: 总共有 2 门课程。学习课程 1 之前,你需要完成课程 0。所以这是可能的。

示例 2:

输入: 2, [[1,0],[0,1]]
输出: false
解释: 总共有 2 门课程。学习课程 1 之前,你需要先完成​课程 0;并且学习课程 0 之前,你还应先完成课程 1。这是不可能的。

说明:

  1. 输入的先决条件是由边缘列表表示的图形,而不是邻接矩阵。详情请参见图的表示法。
  2. 你可以假定输入的先决条件中没有重复的边。

提示:

  1. 这个问题相当于查找一个循环是否存在于有向图中。如果存在循环,则不存在拓扑排序,因此不可能选取所有课程进行学习。
  2. 通过 DFS 进行拓扑排序 - 一个关于Coursera的精彩视频教程(21分钟),介绍拓扑排序的基本概念。
  3. 拓扑排序也可以通过 BFS 完成。

这道题的思路是找图中是否存在环结构,如果存在环结构,就返回false,否则返回true,所以这道题简化成在找寻有向图是否存在环结构,我们使用邻接表来表示图结构,如果存在指向u到v的一条边,意味着v的课程需要先修u,使用vector<unordered_set<int>> graph来保存图结构。

思路一:BFS,步骤为:首先构建图结构,然后寻找每个节点的入度(indegree),找寻入度为0的节点,如果找不到直接返回false(因为存在圆环),然后把这个节点的邻接点的入度都减一,再寻找每个节点的入度是否为0,一直重复以上操作,如果没有返回false,最后返回true,证明图中没有圆环。

参考代码:

class Solution {
public:
vector<unordered_set<int>> make_graph(int numCourses, vector<pair<int, int>>& prerequisites) {vector<unordered_set<int>> graph(numCourses);for (auto item : prerequisites) {graph[item.second].insert(item.first);}return graph;
}
vector<int> calculate_indegree(vector<unordered_set<int>> &graph) {vector<int> indegree_node(graph.size());for (auto neibors : graph) {for (auto neibor : neibors) {indegree_node[neibor]++;}}return indegree_node;
}
bool canFinish(int numCourses, vector<pair<int, int>>& prerequisites) {vector<unordered_set<int>> graph = make_graph(numCourses, prerequisites);vector<int> indegree_node = calculate_indegree(graph);for (int i = 0; i < numCourses; i++) {int j = 0;for (; j < numCourses; j++) {if (indegree_node[j]==0) break;}if (j == numCourses) return false;indegree_node[j] = -1;for (auto neibor : graph[j]) {indegree_node[neibor]--;}}return true;
}
};

思路二:DFS,采用深搜的思路有点不一样,每次寻找一个节点,然后对其邻接点的每一个节点再次寻找其周围的邻接点,如果发现这个节点已经在之前找过了,证明有环,返回false,否则一直遍历结束。这里其实是对每一个节点(startVertex)都采用dfs,所以我们定义两个bool数组来保存:1 visited数组,迄今为止遍历到的所有节点的路径(即节点是否被访问过);2 onPath数组,保存每一次dfs的节点路径。

对于visited数组,只会被赋值true,一旦这个节点被赋值为true,意味着这个节点被访问过且经过这个节点的路径一定无环(因为我们是通过onPath数组来寻找是否有环的,和visited无关)

对于onPath数组,在每次dfs访问到节点时被赋值为true,退出栈时又被赋值为false(相当于对于下一次起始节点startVertex的dfs而言onPath全是false,onPath只对每一次dfs负责)

参考代码:

class Solution {
public:
vector<unordered_set<int>> make_graph(int numCourses, vector<pair<int, int>>& prerequisites) {vector<unordered_set<int>> graph(numCourses);for (auto item : prerequisites) {graph[item.second].insert(item.first);}return graph;
}
bool has_cycle(vector<unordered_set<int>> &graph, vector<int> &visited, vector<int> &onPath,int startVertex) {if (visited[startVertex]) return false;visited[startVertex] = onPath[startVertex] = true;for (auto neibor : graph[startVertex]) {if (onPath[neibor] || has_cycle(graph,visited,onPath,neibor)) {return true;}}onPath[startVertex] = false;return false;
}
bool canFinish(int numCourses, vector<pair<int, int>>& prerequisites) {vector<unordered_set<int>> graph = make_graph(numCourses, prerequisites);vector<int> visited(numCourses, false), onPath(numCourses, false);for (int i = 0; i < numCourses; i++) {if (!visited[i] && has_cycle(graph,visited,onPath,i)) {return false;}}return true;
}
};

Course Schedule 课程表相关推荐

  1. 207. Course Schedule 课程表

    你这个学期必须选修 numCourse 门课程,记为 0 到 numCourse-1 . 在选修某些课程之前需要一些先修课程. 例如,想要学习课程 0 ,你需要先完成课程 1 ,我们用一个匹配来表示他 ...

  2. [leetcode]207. Course Schedule课程表

    在一个有向图中,每次找到一个没有前驱节点的节点(也就是入度为0的节点),然后把它指向其他节点的边都去掉,重复这个过程(BFS),直到所有节点已被找到,或者没有符合条件的节点(如果图中有环存在). /* ...

  3. 面试刷题LeetCode经典100道

    准备面试刷题,100道经典LeetCode题目奉上. 题号 英文题名 中文题名 难度 likes 数 标签 1 Two Sum 两数之和 Easy 11712 数组,哈希表 2 Add Two Num ...

  4. School English(转帖)

    校园英语 ( 5 ):各种名称 选自<中小学英语活动素材库 >,见本网首页"经典 资料介绍"栏目) 1 .学校名称(School names) Shuguang Kin ...

  5. 20210101英语单词学习(仅供自己记录)

    Vocabulary Lists: scramble choke chuckle ammunition seminar boot curriculum obnoxious transformative ...

  6. 铁大课表 测试分析报告

    铁大课表 测试分析报告                   第七小组:闫立新.曹锦锋.李夏蕾. 苏海岩.王伟光.杨世超   2014年5月9日   目录 1引言... 3 1.1编写目的... 3 1 ...

  7. 程序员应该如何学习算法?

    算法不是纯粹拼智商的,初学者不要上来直接撸<算法导论>!这是血泪 建议一:首先你得会一门程序设计语言 建议二:基础知识,数据结构,推荐大家看一下<大话数据结构>这本书,这本书看 ...

  8. LeetCode Top 100 Liked 点赞最高的 100 道算法题

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 公众号:负雪明烛 本文关键词:刷题顺序,刷题路径,好题,top100,怎么刷题,Leet ...

  9. leetcode 210. Course Schedule II | 210. 课程表 II(Java)

    题目 https://leetcode.com/problems/course-schedule-ii/ 题解 本题与 leetcode 207. Course Schedule 基本相同,代码只需要 ...

最新文章

  1. Angular - - ngReadonly、ngSelected、ngDisabled
  2. SPSS数据记录的选择(Select Cases)
  3. 【论文笔记】Region-based Convolutional Networks for Accurate Object Detection and Segmentation
  4. flink HA高可用Standalone集群搭建
  5. react学习(40)----react中的jsx简介
  6. SpringBoot中前后端数据交互
  7. python学习笔记|SQLite数据库基本知识
  8. windows电脑快捷键大全 - 高手总是很酷的
  9. 【网络技术题库梳理11】第三道大题——DHCP报文
  10. java 释放句柄_Java文件句柄释放
  11. 干了5年的前端,实在熬不动了...
  12. 现代法谱估计(3)Burg算法MATLAB及Python实现
  13. 京东到家评价系统存储架构演进
  14. 长篇故事| 世上的感情真的需要门当户对吗?
  15. WPF导出发布安装包,无法验证发行者解决办法
  16. 数据挖掘(python实现)—认识数据
  17. PTA 7-23 求序列立方和
  18. 项目起名的一些小单词
  19. 【repo使用指南】
  20. LeetCode-378.有序矩阵中第k小的元素、二分查找

热门文章

  1. 支持向量机(Support Vector Machine)原理总结(二)
  2. 学习大数据技术,需要具备哪些【数学知识】?你了解了吗?
  3. JavaScript递归函数实现斐波那契数列、黄金分割数列,递归定义与用法实例分析,
  4. css 字体颜色阶梯过渡,CSS3——过渡(transition)
  5. 网页定时自动截图实现方法
  6. 三菱J4伺服驱动器错误代码AE6.0强制停止警告 解决方法
  7. Springboot用HttpServletRequest作为controller入参后接收不到请求
  8. ABP +VUE Elment 通用高级查询(右键菜单)设计+LINQ通用类Expression<Func<TFields, bool>>方法
  9. 微信小程序直播前端实现
  10. 概率论与数理统计复习一(伽马函数、正态分布、瑞利分布、线性相关、独立)