public class Solution {
public boolean canFinish(int numCourses, int[][] prerequisites) {
if (numCourses < 0 || prerequisites == null) return false;
if (prerequisites.length == 0) return true;
List<List<Integer>> adjListsGraph = new ArrayList<>();
for (int i = 0; i < numCourses; i++) adjListsGraph.add(new ArrayList<>());
for (int[] prerequisite : prerequisites) adjListsGraph.get(prerequisite[1]).add(prerequisite[0]);
List<Integer> res = new ArrayList<>();
boolean[] visited = new boolean[numCourses];
boolean[] onVisitingPath = new boolean[numCourses];
for (int i = 0; i < numCourses; i++) {
if (!visited[i] && !canFinish(i, adjListsGraph, visited, onVisitingPath)) return false;
}
return true;
}
private boolean canFinish(int courseNum, List<List<Integer>> adjListsGraph, boolean[] visited, boolean[] onVisitingPath) {
if (visited[courseNum]) return true;
onVisitingPath[courseNum] = true;
for (int dependent : adjListsGraph.get(courseNum)) {
if (onVisitingPath[dependent] || (!visited[dependent] && !canFinish(dependent, adjListsGraph, visited, onVisitingPath))) {
return false;
}
}
onVisitingPath[courseNum] = false;
visited[courseNum] = true;
return true;
}
}