LeetCode 210. 课程表 II
210. 课程表 II
解题思路:
解法一:
拓扑排序。先用vector
建图,并统计每个节点的入度,找到入度为0的点,遍历整个图,在遍历完一个点要把与该点邻接的点的入度减一,找到下一个入度为0的点继续遍历。最后在查看是否所有的点的入度都为0,如果都为0返回答案,否则图中存在环路,返回空。
class Solution {
public:
vector<int> findOrder(int numCourses, vector<vector<int>>& prerequisites) {
vector<int> ans;
vector<int> deg(numCourses);
vector<vector<int>> edge(numCourses);
for (const auto &vec : prerequisites) {
++deg[vec[1]];
edge[vec[0]].push_back(vec[1]);
}
queue<int> q;
for (int i = 0; i < numCourses; ++ i) {
if (deg[i] == 0) q.push(i);
}
while(!q.empty()) {
int val = q.front(); q.pop();
ans.push_back(val);
for (auto chil : edge[val]) {
if (--deg[chil] == 0) {
q.push(chil);
}
}
}
for (int i = 0; i < numCourses; ++ i) {
if (deg[i] != 0) return {};
}
reverse(ans.begin(), ans.end());
return ans;
}
};
解法二:
DFS搜图+判环。用DFS来搜索图中每个点相邻的节点,同时注意判断环路。我们将当前正在搜索的点标记为1,还未搜索的点标记为0,搜索结束的点标记为2,如果正在搜索的点再次被搜索到说明图中存在环路。
//DFS搜图
class Solution {
public:
void DFS(int node) {
vis[node] = 1; //将节点标记为搜索中,如果在搜索中在被搜索到说明有环
for (auto chil : edge[node]) {
if (vis[chil] == 0) {
DFS(chil);
if (!flag) return;
}
if (vis[chil] == 1) {
flag = false;
return;
}
}
ans.push_back(node);
vis[node] = 2; //标记为搜索结束
return;
}
vector<int> findOrder(int numCourses, vector<vector<int>>& prerequisites) {
edge.resize(numCourses);
vis.resize(numCourses);
for (const auto &vec : prerequisites)
edge[vec[0]].push_back(vec[1]);
flag = true;
for (int i = 0; i < numCourses; ++ i) {
if (!vis[i]) DFS(i);
}
if (!flag) ans.clear();
return ans;
}
private:
vector<vector<int>> edge;
vector<int> ans;
vector<int> vis;
bool flag;
};
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通