还有210课程表2,以及一道困难的课程表3
感觉是和图相关的理论。不太会
Wed Aug 24 14:17:33 CST 2022 更新
/*
* @lc app=leetcode.cn id=207 lang=cpp
*
* [207] 课程表
*/
// @lc code=start
class Solution {
public:
vector<vector<int>> edges;
vector<int> visited;
bool valid = true;
void dfs(int c) {
visited[c] = 1;
for (auto& v : edges[c]) {
if (visited[v] == 1) {
valid = false;
return;
} else if (visited[v] == 0) {
dfs(v);
if (valid == false) {
return;
}
}
}
visited[c] = 2;
return;
}
bool canFinish(int numCourses, vector<vector<int>>& prerequisites) {
/**
一个很经典的图论 拓扑排序问题
思路分为2种
一种正向遍历 从每个可以先学的点出发 最终完成遍历
一种反向遍历 对于一个点 如果它的所有后继都已经被遍历 再遍历它
*/
edges.resize(numCourses);
visited = vector<int>(numCourses);
for (auto prerequisity: prerequisites) {
edges[prerequisity[1]].push_back(prerequisity[0]);
}
for (int i = 0; i < numCourses; i++) {
if (!visited[i]) {
dfs(i);
if (!valid) break;
}
}
return valid;
}
};
// @lc code=end
标准的正向遍历,思维类似bfs
/*
* @lc app=leetcode.cn id=207 lang=cpp
*
* [207] 课程表
*/
// @lc code=start
class Solution {
public:
bool canFinish(int numCourses, vector<vector<int>>& prerequisites) {
vector<vector<int>> edges(numCourses);
vector<int> in_edges(numCourses);
int num_ok = 0;
for (auto& prerequisity: prerequisites) {
edges[prerequisity[1]].push_back(prerequisity[0]);
in_edges[prerequisity[0]]++;
}
queue<int> q;
for (int i = 0; i < numCourses; i++) {
if (in_edges[i] == 0) {
q.push(i);
}
}
while (!q.empty()) {
int u = q.front();
q.pop();
num_ok++;
// 注意这里 u是出点 v是入点
for (auto& v: edges[u]) {
in_edges[v]--;
if (in_edges[v] == 0) {
q.push(v);
}
}
}
return num_ok == numCourses;
}
};
// @lc code=end
Your runtime beats 97.94 % of cpp submissions