[LeetCode] Course Schedule

简介: As suggested by the hints, this problem is equivalent to detecting a cycle in the graph represented by prerequisites.

As suggested by the hints, this problem is equivalent to detecting a cycle in the graph represented by prerequisites. Both BFS and DFS can be used to solve it using the idea oftopological sort. If you find yourself unfamiliar with these concepts, you may refer to their wikipedia pages. Specifically, you may only need to refer to the link in the third hint to solve this problem.

Since pair<int, int> is inconvenient for the implementation of graph algorithms, we first transform it to a graph. If course u is a prerequisite of course v, we will add a directed edge from node u to node v.


BFS

BFS uses the indegrees of each node. We will first try to find a node with 0 indegree. If we fail to do so, there must be a cycle in the graph and we return false. Otherwise we have found one. We set its indegree to be -1 to prevent from visiting it again and reduce the indegrees of all its neighbors by 1. This process will be repeated for n (number of nodes) times. If we have not returned false, we will return true.

 1 class Solution {
 2 public:
 3     bool canFinish(int numCourses, vector<pair<int, int>>& prerequisites) {
 4         vector<unordered_set<int>> graph = make_graph(numCourses, prerequisites);
 5         vector<int> degrees = compute_indegree(graph);
 6         for (int i = 0; i < numCourses; i++) {
 7             int j = 0;
 8             for (; j < numCourses; j++)
 9                 if (!degrees[j]) break;
10             if (j == numCourses) return false;
11             degrees[j] = -1;
12             for (int neigh : graph[j])
13                 degrees[neigh]--;
14         }
15         return true;
16     }
17 private:
18     vector<unordered_set<int>> make_graph(int numCourses, vector<pair<int, int>>& prerequisites) {
19         vector<unordered_set<int>> graph(numCourses);
20         for (auto pre : prerequisites)
21             graph[pre.second].insert(pre.first);
22         return graph;
23     }
24     vector<int> compute_indegree(vector<unordered_set<int>>& graph) {
25         vector<int> degrees(graph.size(), 0);
26         for (auto neighbors : graph)
27             for (int neigh : neighbors)
28                 degrees[neigh]++;
29         return degrees;
30     }
31 };

DFS

For DFS, it will first visit a node, then one neighbor of it, then one neighbor of this neighbor... and so on. If it meets a node which was visited in the current process of DFS visit, a cycle is detected and we will return false. Otherwise it will start from another unvisited node and repeat this process till all the nodes have been visited. Note that you should make two records: one is to record all the visited nodes and the other is to record the visited nodes in the current DFS visit.

The code is as follows. We use a vector<bool> visited to record all the visited nodes and another vector<bool> onpath to record the visited nodes of the current DFS visit. Once the current visit is finished, we reset the onpath value of the starting node to false.

 1 class Solution {
 2 public:
 3     bool canFinish(int numCourses, vector<pair<int, int>>& prerequisites) {
 4         vector<unordered_set<int>> graph = make_graph(numCourses, prerequisites);
 5         vector<bool> onpath(numCourses, false), visited(numCourses, false);
 6         for (int i = 0; i < numCourses; i++)
 7             if (!visited[i] && dfs_cycle(graph, i, onpath, visited))
 8                 return false;
 9         return true;
10     }
11 private:
12     vector<unordered_set<int>> make_graph(int numCourses, vector<pair<int, int>>& prerequisites) {
13         vector<unordered_set<int>> graph(numCourses);
14         for (auto pre : prerequisites)
15             graph[pre.second].insert(pre.first);
16         return graph;
17     } 
18     bool dfs_cycle(vector<unordered_set<int>>& graph, int node, vector<bool>& onpath, vector<bool>& visited) {
19         if (visited[node]) return false;
20         onpath[node] = visited[node] = true; 
21         for (int neigh : graph[node])
22             if (onpath[neigh] || dfs_cycle(graph, neigh, onpath, visited))
23                 return true;
24         return onpath[node] = false;
25     }
26 }; 

 

目录
相关文章
|
索引
LeetCode 207. Course Schedule
现在你总共有 n 门课需要选,记为 0 到 n-1。 在选修某些课程之前需要一些先修课程。 例如,想要学习课程 0 ,你需要先完成课程 1 ,我们用一个匹配来表示他们: [0,1] 给定课程总量以及它们的先决条件,判断是否可能完成所有课程的学习?
91 0
LeetCode 207. Course Schedule
[LeetCode] Course Schedule III 课程清单之三
There are n different online courses numbered from 1 to n. Each course has some duration(course length) tand closed on dth day.
1101 0
LeetCode - 207. Course Schedule
207. Course Schedule  Problem's Link  ---------------------------------------------------------------------------- Mean:  给定一个有向图,判断是否存在top_sort序列.
1009 0
[LeetCode] Course Schedule II
Well, this problem is spiritually similar to to Course Schedule. You only need to store the nodes in the order you visit into a vector during BFS or DFS.
703 0
|
4月前
|
Unix Shell Linux
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行
本文提供了几个Linux shell脚本编程问题的解决方案,包括转置文件内容、统计词频、验证有效电话号码和提取文件的第十行,每个问题都给出了至少一种实现方法。
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行
|
5月前
|
Python
【Leetcode刷题Python】剑指 Offer 32 - III. 从上到下打印二叉树 III
本文介绍了两种Python实现方法,用于按照之字形顺序打印二叉树的层次遍历结果,实现了在奇数层正序、偶数层反序打印节点的功能。
69 6
|
5月前
|
搜索推荐 索引 Python
【Leetcode刷题Python】牛客. 数组中未出现的最小正整数
本文介绍了牛客网题目"数组中未出现的最小正整数"的解法,提供了一种满足O(n)时间复杂度和O(1)空间复杂度要求的原地排序算法,并给出了Python实现代码。
137 2
|
2月前
|
机器学习/深度学习 人工智能 自然语言处理
280页PDF,全方位评估OpenAI o1,Leetcode刷题准确率竟这么高
【10月更文挑战第24天】近年来,OpenAI的o1模型在大型语言模型(LLMs)中脱颖而出,展现出卓越的推理能力和知识整合能力。基于Transformer架构,o1模型采用了链式思维和强化学习等先进技术,显著提升了其在编程竞赛、医学影像报告生成、数学问题解决、自然语言推理和芯片设计等领域的表现。本文将全面评估o1模型的性能及其对AI研究和应用的潜在影响。
78 1