Course Schedule
Problem
You are given an array prerequisites where prerequisites[i] = [a, b] indicates that you must take course b first if you want to take course a.
The pair [0, 1], indicates that must take course 1 before taking course 0.
There are a total of numCourses courses you are required to take, labeled from 0 to numCourses - 1.
Return true if it is possible to finish all courses, otherwise return false.
Examples
Example 1:
Input: numCourses = 2, prerequisites = [[0,1]]
Output: true
Explanation: First take course 1 (no prerequisites) and then take course 0.
Example 2:
Input: numCourses = 2, prerequisites = [[0,1],[1,0]]
Output: false
Explanation: In order to take course 1 you must take course 0, and to take course 0 you must take course 1. So it is impossible.
Constraints
1 <= numCourses <= 10000 <= prerequisites.length <= 1000prerequisites[i].length == 20 <= a[i], b[i] < numCourses- All
prerequisitepairs are unique.
You should aim for a solution with O(V + E) time and O(V + E) space, where V is the number of courses (nodes) and E is the number of prerequisites (edges).
Solution
prerequisite[i] = [A,B] means that B -> A as an edge for B must be taken before A. We track the indegree for each node, and map the adjacency list for the edge directions. We start a queue with courses with no prerequisites. Every time we take a course, we decrement the counter for any course its a prerequisite for, and if that course now longer has blockers, we add to the queue.
class Solution {
public:
bool canFinish(int numCourses, vector<vector<int>>& prerequisites) {
std::vector<int> indegree(numCourses, 0);
std::vector<std::vector<int>> adj(numCourses);
// prerequisite[i] = [A,B]
// B -> A i.e. B is a prereq for A
for (const auto &prerequisite : prerequisites) {
++indegree[prerequisite[0]];
adj[prerequisite[1]].push_back(prerequisite[0]);
}
// Start off by taking courses with no prereqs
std::queue<int> open;
for (int i = 0; i < numCourses; ++i) {
if (indegree[i] == 0) {
open.push(i);
}
}
int courses_taken = 0;
while (!open.empty()) {
int course = open.front();
open.pop();
++courses_taken;
for (const auto &c : adj[course]) {
--indegree[c];
if (indegree[c] == 0) {
open.push(c);
}
}
}
return courses_taken == numCourses;
}
};