[LeetCode] 207. Course Schedule
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
.
- For example, the pair
[0, 1]
, indicates that to take course0
you have to first take course1
.
Return true
if you can finish all courses. Otherwise, return false
.
Example 1:
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.
Example 2:
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.
Constraints:
1 <= numCourses <= 2000
0 <= prerequisites.length <= 5000
prerequisites[i].length == 2
0 <= ai, bi < numCourses
- All the pairs prerequisites[i] are unique.
课程表。
你这个学期必须选修 numCourses 门课程,记为 0 到 numCourses - 1 。
在选修某些课程之前需要一些先修课程。 先修课程按数组 prerequisites 给出,其中 prerequisites[i] = [ai, bi] ,表示如果要学习课程 ai 则 必须 先学习课程 bi 。
例如,先修课程对 [0, 1] 表示:想要学习课程 0 ,你需要先完成课程 1 。
请你判断是否可能完成所有课程的学习?如果可以,返回 true ;否则,返回 false 。来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/course-schedule
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
典型的拓扑排序题目。拓扑排序又称之为有向无环图(DAG)。拓扑排序的定义在这里就不赘述了。这个题目有多种做法,此处我分享一个 BFS 的思路。首先为所有课程创建一个入度表 indegree,遍历所有的课程。所有课程的 prerequisites 都以一个 pair[0, 1] 表示(0的先修课程是1),所以遍历所有的 pair[0],建立所有课程的入度表。此时再遍历这个入度表,将入度表中所有为 0(没有先修课程)的元素加入一个队列。遍历这个队列,每弹出一个元素 cur,就减去一门课 res--,去 prerequisites 中看是否有其他课程 pair[0] 的先修课程是 cur,若有,则在入度表里面找到这个 pair[0] 并减 1。如果这个 pair[0] 也被减到入度为 0 了,则把他加入队列继续查找,看这个 pair[0] 是否是别的课的先修课。最后会跳出 while 循环,跳出的时候判断是不是所有课程 res 都遍历完了。
时间O(V + E)
空间O(n)
Java实现
1 class Solution { 2 public boolean canFinish(int numCourses, int[][] prerequisites) { 3 int[] indegree = new int[numCourses]; 4 int res = numCourses; 5 for (int[] pair : prerequisites) { 6 indegree[pair[0]]++; 7 } 8 9 // 把所有入度为0的节点加入队列 10 // 入度为0说明没有先修课程 11 Queue<Integer> queue = new LinkedList<>(); 12 for (int i = 0; i < indegree.length; i++) { 13 if (indegree[i] == 0) { 14 queue.offer(i); 15 } 16 } 17 18 // 遍历所有入度为0的课程 19 while (!queue.isEmpty()) { 20 int pre = queue.poll(); 21 res--; 22 // 看是否有其他课程的先修课程是pre 23 for (int[] pair : prerequisites) { 24 if (pair[1] == pre) { 25 indegree[pair[0]]--; 26 if (indegree[pair[0]] == 0) { 27 queue.offer(pair[0]); 28 } 29 } 30 } 31 } 32 return res == 0; 33 } 34 }
相关题目