Tags: leetcode graph bfs java python
There are a total of numCourses courses you have to take, labeled from 0 to numCourses - 1. You are given an array prerequisites where prerequisites[i] = [ai, bi] indicates that you must take course bi first if you want to take course ai.
Return true if you can finish all courses. Otherwise, return false.
Input: numCourses = 2, prerequisites = [[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.
Input: numCourses = 2, prerequisites = [[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.
Lets take a good test case like
numCourses = 5
prerequisites = [[1,4],[2,4],[3,1],[3,2]]
Here
We can visuallize it as a directed graph.
This problem is equivalent to finding if a cycle exists in a directed graph. If a cycle exists, no topological ordering exists and therefore it will be impossible to take all courses.
| class Solution { | |
| Map<Integer, List> adj = new HashMap<>(); | |
| public List<Integer> getNeighbour(int n){ | |
| return new ArrayList<>(adj.get(n)); | |
| } | |
| public boolean canFinish(int numCourses, int[][] prerequisites) { | |
| if (prerequisites.length == 0){ | |
| return true; | |
| } | |
| int[] indegree = new int[numCourses]; | |
| for (int i = 0; i < prerequisites.length; i++){ | |
| adj.computeIfAbsent(prerequisites[i][1], | |
| k -> new ArrayList<>()).add(prerequisites[i][0]); | |
| indegree[prerequisites[i][0]]++; | |
| } | |
| Deque<Integer> queue = new ArrayDeque<>(); | |
| for (int i = 0; i < indegree.length; i++){ | |
| if (indegree[i] == 0){ | |
| queue.offer(i); | |
| } | |
| } | |
| int count = 0; | |
| while (!queue.isEmpty()) { | |
| int current = queue.poll(); | |
| if (indegree[current] == 0 ){ | |
| count++; | |
| } | |
| if (!adj.containsKey(current)) { | |
| continue; | |
| } | |
| for (int neighbour : getNeighbour(current)){ | |
| indegree[neighbour]--; | |
| if (indegree[neighbour] == 0 ){ | |
| queue.offer(neighbour); | |
| } | |
| } | |
| } | |
| return numCourses == count; | |
| } | |
| } |
Time complexity:
V : numCourses & E : prerequisites