|
1 | 1 | // Time: O(|V| + |E|)
|
2 | 2 | // Space: O(|E|)
|
3 | 3 |
|
4 |
| -// Topological sort solution. |
| 4 | +// dfs solution |
5 | 5 | class Solution {
|
6 | 6 | public:
|
7 | 7 | bool canFinish(int numCourses, vector<vector<int>>& prerequisites) {
|
8 |
| - // Store courses with in-degree zero. |
9 |
| - queue<int> zeroInDegree; |
10 |
| - |
11 |
| - // in-degree, out-degree |
12 |
| - unordered_map<int, unordered_set<int>> inDegree; |
13 |
| - unordered_map<int, unordered_set<int>> outDegree; |
14 |
| - for (int i = 0; i < prerequisites.size(); ++i) { |
15 |
| - inDegree[prerequisites[i][0]].insert(prerequisites[i][1]); |
16 |
| - outDegree[prerequisites[i][1]].insert(prerequisites[i][0]); |
| 8 | + unordered_map<int, unordered_set<int>> in_degree, out_degree; |
| 9 | + for (const auto& p : prerequisites) { |
| 10 | + in_degree[p[0]].emplace(p[1]); |
| 11 | + out_degree[p[1]].emplace(p[0]); |
17 | 12 | }
|
18 |
| - |
19 |
| - // Put all the courses with in-degree zero into queue. |
20 |
| - for(int i = 0; i < numCourses; ++i) { |
21 |
| - if(inDegree.find(i) == inDegree.end()) { |
22 |
| - zeroInDegree.push(i); |
| 13 | + queue<int> q; |
| 14 | + for (int i = 0; i < numCourses; ++i) { |
| 15 | + if (!in_degree.count(i)) { |
| 16 | + q.emplace(i); |
23 | 17 | }
|
24 | 18 | }
|
25 |
| - |
26 |
| - // V+E |
27 |
| - while(!zeroInDegree.empty()) { |
28 |
| - // Take the course which prerequisites are all taken. |
29 |
| - int prerequisite = zeroInDegree.front(); |
30 |
| - zeroInDegree.pop(); |
31 |
| - for (const auto & course: outDegree[prerequisite]) { |
32 |
| - // Update info of all the courses with the taken prerequisite. |
33 |
| - inDegree[course].erase(prerequisite); |
34 |
| - // If all the prerequisites are taken, add the course to the queue. |
35 |
| - if (inDegree[course].empty()) { |
36 |
| - zeroInDegree.push(course); |
| 19 | + while (!q.empty()) { |
| 20 | + const auto node = q.front(); q.pop(); |
| 21 | + for (const auto& i : out_degree[node]) { |
| 22 | + in_degree[i].erase(node); |
| 23 | + if (in_degree[i].empty()) { |
| 24 | + q.emplace(i); |
| 25 | + in_degree.erase(i); |
37 | 26 | }
|
38 | 27 | }
|
39 |
| - // Mark the course as taken. |
40 |
| - outDegree.erase(prerequisite); |
| 28 | + out_degree.erase(node); |
41 | 29 | }
|
42 |
| - |
43 |
| - // All of the courses have been taken. |
44 |
| - if (!outDegree.empty()) { |
45 |
| - return false; |
| 30 | + return in_degree.empty() && out_degree.empty(); |
| 31 | + } |
| 32 | +}; |
| 33 | + |
| 34 | +// Time: O(|V| + |E|) |
| 35 | +// Space: O(|E|) |
| 36 | +// bfs solution |
| 37 | +class Solution2 { |
| 38 | +public: |
| 39 | + bool canFinish(int numCourses, vector<vector<int>>& prerequisites) { |
| 40 | + unordered_map<int, unordered_set<int>> in_degree, out_degree; |
| 41 | + for (const auto& p : prerequisites) { |
| 42 | + in_degree[p[0]].emplace(p[1]); |
| 43 | + out_degree[p[1]].emplace(p[0]); |
| 44 | + } |
| 45 | + vector<int> stk; |
| 46 | + for (int i = 0; i < numCourses; ++i) { |
| 47 | + if (!in_degree.count(i)) { |
| 48 | + stk.emplace_back(i); |
| 49 | + } |
| 50 | + } |
| 51 | + while (!stk.empty()) { |
| 52 | + const auto node = stk.back(); stk.pop_back(); |
| 53 | + for (const auto& i : out_degree[node]) { |
| 54 | + in_degree[i].erase(node); |
| 55 | + if (in_degree[i].empty()) { |
| 56 | + stk.emplace_back(i); |
| 57 | + in_degree.erase(i); |
| 58 | + } |
| 59 | + } |
| 60 | + out_degree.erase(node); |
46 | 61 | }
|
47 |
| - |
48 |
| - return true; |
| 62 | + return in_degree.empty() && out_degree.empty(); |
49 | 63 | }
|
50 | 64 | };
|
0 commit comments