Files
leetcode-master/problems/0207.课程表.md
programmercarl 94a4e81265 Update
2024-05-15 11:35:26 +08:00

66 lines
2.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<p align="center">
<a href="https://www.programmercarl.com/xunlian/xunlianying.html" target="_blank">
<img src="../pics/训练营.png" width="1000"/>
</a>
<p align="center"><strong><a href="./qita/join.md">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们受益!</strong></p>
拓扑排序指的是一种 解决问题的大体思路, 而具体算法,可能是 广搜 可能是深搜。
大家可能发现 各式各样的解法,纠结哪个是拓扑排序?
只要能在把 有向无环图 进行线性排序 的算法 都可以叫做 拓扑排序。
引用与任务调度,课程安排等等。
「拓扑排序」是专门应用于有向图的算法;
把一个 有向无环图 转成 线性的排序 就叫 拓扑排序。
拓扑排序Kahn 算法,其实就是广度优先遍历的思路)
这道题的做法同样适用于第 210 题。
```CPP
class Solution {
public:
bool canFinish(int numCourses, vector<vector<int>>& prerequisites) {
vector<int> inDegree(numCourses, 0);
unordered_map<int, vector<int>> umap;
for (int i = 0; i < prerequisites.size(); i++) {
// prerequisites[i][0] 是 课程入度prerequisites[i][1] 是课程出度
// 即: 上课prerequisites[i][0] 之前必须先上课prerequisites[i][1]
// prerequisites[i][1] -> prerequisites[i][0]
inDegree[prerequisites[i][0]]++;//当前课程入度值+1
umap[prerequisites[i][1]].push_back(prerequisites[i][0]); // 添加 prerequisites[i][1] 指向的课程
}
queue<int> que;
for (int i = 0; i < numCourses; i++) {
if (inDegree[i] == 0) que.push(i); // 所有入度为0即为 开头课程 加入队列
}
int count = 0;
while (que.size()) {
int cur = que.front(); //当前选的课
que.pop();
count++; // 选课数+1
vector<int> courses = umap[cur]; //获取这门课指向的课程,也就是这么课的后续课
if (courses.size()) { // 有后续课
for (int i = 0; i < courses.size(); i++) {
inDegree[courses[i]]--; // 它的后续课的入度-1
if (inDegree[courses[i]] == 0) que.push(courses[i]); // 如果入度为0加入队列
}
}
}
if (count == numCourses) return true;
return false;
}
};
```
<p align="center">
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
</a>