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;
};