Problem 207. Course Schedule
-
题目描述
There are a total of n courses you have to take, labeled from 0 to n-1.Some courses may have prerequisites, for example to take course 0 you have to first take course 1, which is expressed as a pair: [0,1]
Given the total number of courses and a list of prerequisite pairs, is it possible for you to finish all courses?
Example 2:
Input: 2, [[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.
-
解题思路
题目意思是有 n 门课,课程编号分别为 0 到 n-1,现在给定二维数组 prerequisites 表示课程之间的约束关系,例如 prerequisites[0] = [0, 1] 表示只有先上了课程1之后才能上课程 0,问能否找到一个合适的排课方案。解题思路如下:
- 建立一个二维 vector 对象 graph,其中 graph[i] 表示以 i 为先导课程的所有课程的集合;建立一维 vector 变量 requireNum,其中 requireNum[i] 表示课程 i 需要的先导课程的数量。
- 建立一个队列 q,对 requireNum 进行遍历,将 requireNum[i] = 0 的所有课程编号 i 存入队列 q中。此时 q 中的元素表示可以直接开课的课程(无需先导课程或先导课程已修的课程)。
- 对 q 中的所有元素 cur 进行遍历,每访问完一个 cur 表示课程 cur 已经修完。此时将 graph[cur] 中的每一个元素的 requireNum 值减 1,表示该课程需要的先导课程数量减 1,若所需先导课程数量变为 0,表示此课程可以上了,并加入到队列 q 中。
- 对 q 中所有的元素进行遍历后,检查 requireNum 中每一个元素的值,如果出现不为 0 的情况,则表示至少有一门课无法安排上课,返回 false。
- 代码实现
该算法的 C++ 代码如下:
class Solution {
public:
bool canFinish(int numCourses, vector<pair<int, int> >& prerequisites) {
vector<vector<int> > graph(numCourses, vector<int>(0));
vector<int> requireNum(numCourses, 0);
for(auto pre : prerequisites){
graph[pre.second].push_back(pre.first);
requireNum[pre.first]++;
}
queue<int> q;
for(int i = 0; i < requireNum.size(); ++i)
if(requireNum[i] == 0)
q.push(i);
while(!q.empty()){
int cur = q.front();
q.pop();
for(auto i : graph[cur]){
requireNum[i]--;
if(requireNum[i] == 0)
q.push(i);
}
}
for(auto i : requireNum)
if(i != 0)
return false;
return true;
}
};