-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path207.course-schedule.java
More file actions
142 lines (124 loc) · 3.82 KB
/
Copy path207.course-schedule.java
File metadata and controls
142 lines (124 loc) · 3.82 KB
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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
/*
* @lc app=leetcode id=207 lang=java
*
* [207] Course Schedule
*
* https://leetcode.com/problems/course-schedule/description/
*
* algorithms
* Medium (38.79%)
* Total Accepted: 323.7K
* Total Submissions: 792.8K
* Testcase Example: '2\n[[1,0]]'
*
* There are a total of n courses you have to take, labeled from 0 to n-1.
*
* Some courses may have prerequisites, for example to take course 0 you have
* to first take course 1, which is expressed as a pair: [0,1]
*
* Given the total number of courses and a list of prerequisite pairs, is it
* possible for you to finish all courses?
*
* Example 1:
*
*
* Input: 2, [[1,0]]
* Output: true
* Explanation: There are a total of 2 courses to take.
* To take course 1 you should have finished course 0. So it is possible.
*
* Example 2:
*
*
* Input: 2, [[1,0],[0,1]]
* Output: false
* Explanation: There are a total of 2 courses to take.
* To take course 1 you should have finished course 0, and to take course 0 you
* should
* also have finished course 1. So it is impossible.
*
*
* Note:
*
*
* The input prerequisites is a graph represented by a list of edges, not
* adjacency matrices. Read more about how a graph is represented.
* You may assume that there are no duplicate edges in the input
* prerequisites.
*
*
*/
class Solution {
/** DFS */
public boolean canFinish1(int numCourses, int[][] prerequisites) {
if (numCourses <= 1) {
return true;
}
// Build the graph
Map<Integer, List<Integer>> graph = new HashMap<>();
for (int[] r : prerequisites) {
if (!graph.containsKey(r[0])) {
graph.put(r[0], new ArrayList<>());
}
graph.get(r[0]).add(r[1]);
}
// Traverse the graph and figure out if cycle exists
Set<Integer> visited = new HashSet<>();
for (int i = 0; i < numCourses; i++) {
if (hasCycle(graph, i, visited, new HashSet<>())) {
return false;
}
}
return true;
}
private boolean hasCycle(Map<Integer, List<Integer>> graph, int node, Set<Integer> visited, Set<Integer> path) {
if (path.contains(node)) {
return true;
}
if (visited.contains(node) || !graph.containsKey(node)) {
return false;
}
visited.add(node);
path.add(node);
for (int neighbor : graph.get(node)) {
if (hasCycle(graph, neighbor, visited, path)) {
return true;
}
}
path.remove(node);
return false;
}
// 拓扑排序
public boolean canFinish(int numCourses, int[][] prerequisites) {
int[] incomingEdges = new int[numCourses];
List<Integer>[] edges = new List[numCourses];
for (int i = 0; i < numCourses; i++) {
edges[i] = new LinkedList<>();
}
// Build the graph
for (int[] prerequisite : prerequisites) {
incomingEdges[prerequisite[0]]++;
edges[prerequisite[1]].add(prerequisite[0]);
}
// Try to find all the node with no incoming edge
Queue<Integer> queue = new LinkedList<>();
for (int i = 0; i < numCourses; i++) {
if (incomingEdges[i] == 0) {
queue.offer(i);
}
}
// Do the topological sorting
int edgeCount = prerequisites.length;
while (!queue.isEmpty()) {
int course = queue.poll();
// Remove all the edges
for (int target : edges[course]) {
if (--incomingEdges[target] == 0) {
queue.offer(target);
}
edgeCount--;
}
}
return edgeCount == 0;
}
}