|
4 | 4 |
|
5 | 5 | import java.util.ArrayList;
|
6 | 6 | import java.util.HashMap;
|
7 |
| -import java.util.HashSet; |
| 7 | +import java.util.LinkedList; |
8 | 8 | import java.util.List;
|
9 | 9 | import java.util.Map;
|
10 |
| -import java.util.Set; |
| 10 | +import java.util.Queue; |
11 | 11 |
|
12 | 12 | public class CourseSchedule {
|
13 | 13 | public boolean canFinish(int numCourses, int[][] prerequisites) {
|
14 |
| - final Map<Integer, List<Integer>> dependencyGraph = getDependencyGraph(prerequisites); |
15 |
| - return !containsLoop(dependencyGraph, numCourses); |
16 |
| - } |
| 14 | + final int[] inDegree = getInDegreeValues(prerequisites, numCourses); |
| 15 | + final Queue<Integer> queue = queueWithInDegree0Vertices(inDegree); |
| 16 | + final Map<Integer, List<Integer>> graph = getDependencyGraph(prerequisites); |
17 | 17 |
|
18 |
| - private boolean containsLoop(Map<Integer, List<Integer>> graph, int numCourses) { |
19 |
| - Set<Integer> computed = new HashSet<>(); |
20 |
| - for (int i = 0 ; i < numCourses ; i++) { |
21 |
| - if (graph.containsKey(i)) { |
22 |
| - if (computed.contains(i)) continue; |
23 |
| - if (containsLoop(graph, i, computed)) { |
24 |
| - return true; |
| 18 | + while (!queue.isEmpty()) { |
| 19 | + int vertex = queue.poll(); |
| 20 | + if (graph.containsKey(vertex)) { |
| 21 | + for (int adjacent : graph.get(vertex)) { |
| 22 | + inDegree[adjacent]--; |
| 23 | + if (inDegree[adjacent] == 0) queue.add(adjacent); |
25 | 24 | }
|
26 | 25 | }
|
27 | 26 | }
|
28 |
| - return false; |
| 27 | + |
| 28 | + return allAreZero(inDegree); |
29 | 29 | }
|
30 | 30 |
|
31 |
| - private boolean containsLoop(Map<Integer, List<Integer>> graph, int vertex, Set<Integer> computed) { |
32 |
| - return containsLoop(graph, vertex, computed, new HashSet<>()); |
| 31 | + private boolean allAreZero(int[] array) { |
| 32 | + for (int element : array) { |
| 33 | + if (element != 0) return false; |
| 34 | + } |
| 35 | + return true; |
33 | 36 | }
|
34 | 37 |
|
35 |
| - private boolean containsLoop(Map<Integer, List<Integer>> graph, int vertex, Set<Integer> computed, Set<Integer> visited) { |
36 |
| - if (visited.contains(vertex)) return true; |
37 |
| - if (computed.contains(vertex)) return false; |
38 |
| - visited.add(vertex); |
39 |
| - computed.add(vertex); |
40 |
| - if (graph.containsKey(vertex)) { |
41 |
| - List<Integer> dependsOn = graph.get(vertex); |
42 |
| - for (int dependency : dependsOn) { |
43 |
| - if (containsLoop(graph, dependency, computed, visited)) { |
44 |
| - return true; |
45 |
| - } |
| 38 | + private Queue<Integer> queueWithInDegree0Vertices(int[] inDegrees) { |
| 39 | + final Queue<Integer> queue = new LinkedList<>(); |
| 40 | + for (int i = 0; i < inDegrees.length; i++) { |
| 41 | + if (inDegrees[i] == 0) { |
| 42 | + queue.add(i); |
46 | 43 | }
|
47 | 44 | }
|
48 |
| - visited.remove(vertex); |
49 |
| - return false; |
| 45 | + return queue; |
| 46 | + } |
| 47 | + |
| 48 | + private static int[] getInDegreeValues(int[][] preRequisites, int numCourses) { |
| 49 | + int[] result = new int[numCourses]; |
| 50 | + for (int[] preRequisite: preRequisites) { |
| 51 | + result[preRequisite[1]]++; |
| 52 | + } |
| 53 | + return result; |
50 | 54 | }
|
51 | 55 |
|
52 |
| - private Map<Integer, List<Integer>> getDependencyGraph(int[][] prerequisites) { |
| 56 | + private static Map<Integer, List<Integer>> getDependencyGraph(int[][] prerequisites) { |
53 | 57 | final Map<Integer, List<Integer>> dependencyGraph = new HashMap<>();
|
54 | 58 | for (int[] prerequisite : prerequisites) {
|
55 | 59 | if (!dependencyGraph.containsKey(prerequisite[0])) {
|
|
0 commit comments