-
Notifications
You must be signed in to change notification settings - Fork 15
/
Copy path210. Course Schedule II.cpp
105 lines (87 loc) · 3.05 KB
/
210. Course Schedule II.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
//Approach 2: Using Node Indegree
//Runtime: 24 ms, faster than 81.55% of C++ online submissions for Course Schedule II.
//Memory Usage: 10.9 MB, less than 100.00% of C++ online submissions for Course Schedule II.
//time: O(N), space: O(N)
class Solution {
public:
vector<int> findOrder(int numCourses, vector<vector<int>>& prerequisites) {
vector<int> incomingEdgeCount(numCourses, 0);
vector<vector<int>> edges(numCourses);
for(vector<int>& pre : prerequisites){
incomingEdgeCount[pre[0]]++;
edges[pre[1]].push_back(pre[0]);
}
queue<int> qNoIncomingEdges;
for(int i = 0; i < numCourses; i++){
if(incomingEdgeCount[i] == 0){
qNoIncomingEdges.push(i);
}
}
int remainingEdgeCount = prerequisites.size();
vector<int> ans;
while(!qNoIncomingEdges.empty()){
int cur = qNoIncomingEdges.front(); qNoIncomingEdges.pop();
ans.push_back(cur);
for(int nei : edges[cur]){
remainingEdgeCount--;
if(--incomingEdgeCount[nei] == 0){
qNoIncomingEdges.push(nei);
}
}
}
if(remainingEdgeCount != 0) ans.clear();
return ans;
}
};
//Approach 1: Using Depth First Search
//Runtime: 36 ms, faster than 23.25% of C++ online submissions for Course Schedule II.
//Memory Usage: 13 MB, less than 100.00% of C++ online submissions for Course Schedule II.
//time: O(N), space: O(N)
enum class Color{
WHITE, GRAY, BLACK
};
class Solution {
public:
bool isCyclic;
unordered_map<int, Color> color;
unordered_map<int, vector<int>> adjList;
vector<int> topologicalOrder;
void init(int numCourses){
this->isCyclic = false;
for(int i = 0; i < numCourses; i++){
this->color[i]= Color::WHITE;
}
}
void dfs(int node){
if(this->isCyclic) return;
this->color[node] = Color::GRAY;
for(int nei : this->adjList[node]){
if(this->color[nei] == Color::WHITE){
this->dfs(nei);
}else if(this->color[nei] == Color::GRAY){
this->isCyclic = true;
}
}
this->color[node] = Color::BLACK;
this->topologicalOrder.push_back(node);
}
vector<int> findOrder(int numCourses, vector<vector<int>>& prerequisites) {
this->init(numCourses);
for(vector<int>& pre : prerequisites){
adjList[pre[1]].push_back(pre[0]);
}
for(int i = 0; i < numCourses; i++){
if(this->color[i] == Color::WHITE){
this->dfs(i);
}
}
vector<int> order;
if(!this->isCyclic){
order = vector<int>(numCourses, 0);
for(int i = 0; i < numCourses; i++){
order[i] = this->topologicalOrder[numCourses-i-1];
}
}
return order;
}
};