207. 课程表
class Solution {
public:
bool canFinish(int nums, vector<vector<int>>& pres) {
if (pres.size() == 0 || pres[0].size() == 0) {
return true;
}
vector<vector<int>> paths(nums);
vector<bool> visited(nums);
vector<bool> onPath(nums);
for (int i=0; i<pres.size(); i++) {
int ai = pres[i][0];
int bi = pres[i][1];
paths[bi].push_back(ai);
}
for (int i=0; i<nums; i++) {
dfs(paths, visited, onPath, i);
}
return !hasCircle;
}
void dfs(vector<vector<int>> &paths, vector<bool> &visited, vector<bool> &onPath, int x) {
if (onPath[x]) {
hasCircle = true;
}
if (visited[x]) {
return;
}
visited[x] = true;
onPath[x] = true;
for (int node : paths[x]) {
dfs(paths, visited, onPath, node);
}
onPath[x] = false;
}
private:
bool hasCircle;
};
210. Course Schedule II
class Solution {
public:
vector<int> findOrder(int numCourses, vector<vector<int>>& prerequisites) {
vector<vector<int>> graph(numCourses);
vector<bool> visited(numCourses);
vector<bool> onPath(numCourses);
for (vector<int> vec : prerequisites) {
graph[vec[1]].push_back(vec[0]);
}
for (int i=0; i<numCourses; i++) {
dfs(graph, visited, onPath, i);
}
if (hasCircle) {
return {};
}
visited = vector(numCourses, false);
for (int i=0; i<numCourses; i++) {
postorder(graph, visited, i);
}
reverse(ans.begin(), ans.end());
return ans;
}
void dfs(vector<vector<int>> &graph, vector<bool> &visited, vector<bool> &onPath, int cur) {
if (onPath[cur]) {
hasCircle = true;
return;
}
if (visited[cur]) {
return;
}
visited[cur] = true;
onPath[cur] = true;
for (int next : graph[cur]) {
dfs(graph, visited, onPath, next);
}
onPath[cur] = false;
}
void postorder(vector<vector<int>> &graph, vector<bool> &visited, int cur) {
if (visited[cur]) {
return;
}
visited[cur] = true;
for (int next : graph[cur]) {
postorder(graph, visited, next);
}
ans.push_back(cur);
}
private:
vector<int> ans;
int hasCircle;
};
广度有限搜索,也是更加“标准”的拓扑排序解法
class Solution {
public:
vector<int> findOrder(int n, vector<vector<int>>& prerequisites) {
vector<int> ans;
vector<vector<int>> graph(n);
vector<int> in(n, 0);
for (vector<int> vec : prerequisites) {
int a=vec[0];
int b=vec[1];
graph[b].push_back(a);
in[a]++;
}
queue<int> que;
for (int i=0; i<n; i++) {
if (in[i]==0) {
que.push(i);
}
}
while(!que.empty()) {
int i=que.front();
que.pop();
ans.push_back(i);
for(int node : graph[i]) {
in[node]--;
if (in[node]==0) {
que.push(node);
}
}
}
if (ans.size() != n) {
return {};
} else {
return ans;
}
}
};