(47条消息) 拓扑排序(Topological Sorting)_神奕的专栏-CSDN博客_拓扑排序
拓扑排序的原理如上。
简单的来说就是:对于有向无环图DAG来说,图内无环才能有对应的拓扑排序。
LeetCode207 课程表
207. 课程表 - 力扣(LeetCode) (leetcode-cn.com)
拓扑排序+DFS:
class Solution {
private:
vector<vector<int>> edges; //edges[i][j]中i为前置课程,j表示对应的一系列后继课程
vector<int> visited; //0为未搜索,1为搜索中,2为已完成
bool valid = true; //标记结果,遇到环则更新为false
public:
void dfs(int course) {
visited[course] = 1; //更新 搜索中
//遍历该前置课程的所有后继课程
for(int c : edges[course]) {
//如果后继点为未搜索
if(visited[c] == 0) {
dfs(c);
if(!valid)
return;
}
//如果出现环
else if (visited[c] == 1) {
valid = false;
return;
}
}
visited[course] = 2; //已完成
}
bool canFinish(int numCourses, vector<vector<int>>& prerequisites) {
edges.resize(numCourses);
visited.resize(numCourses);
//把给定的课程关系转换一下,方便遍历某个结点所有的后继点
for(const auto& edge : prerequisites) {
int pre = edge[0], next = edge[1];
edges[pre].push_back(next);
}
//遍历所有课程,对每个点都进行dfs(未出现环时)
for(int i = 0; i < numCourses && valid; i++) {
if(!visited[i])
dfs(i);
}
return valid;
}
};
LeetCode210 课程表II
拓扑排序+DFS
和上一题不同之处只在于多了一个记录拓扑排序的数组,该数组在dfs的末尾添加新元素,并且在返回答案时进行反转。
class Solution {
private:
vector<vector<int>> edges;
vector<int> visited;
vector<int> ans;
bool valid = true;
public:
void dfs(int course) {
visited[course] = 1;
for(int c:edges[course]) {
if(visited[c] == 0) {
dfs(c);
if(!valid)
return;
}
else if(visited[c] == 1) {
valid = false;
return;
}
}
visited[course] = 2;
ans.push_back(course);
}
vector<int> findOrder(int numCourses, vector<vector<int>>& prerequisites) {
edges.resize(numCourses);
visited.resize(numCourses);
for(const auto& edge:prerequisites) {
int pre = edge[1], next = edge[0];
edges[pre].push_back(next);
}
for(int i = 0; i < numCourses && valid; i++) {
if(!visited[i]) {
dfs(i);
}
}
if(!valid)
return {};
reverse(ans.begin(), ans.end());
return ans;
}
};