你这个学期必须选修 numCourses
门课程,记为 0
到 numCourses - 1
。
在选修某些课程之前需要一些先修课程。 先修课程按数组 prerequisites
给出,其中 prerequisites[i] = [ai, bi]
,表示如果要学习课程 ai
则 必须 先学习课程 bi
。
- 例如,先修课程对
[0, 1]
表示:想要学习课程0
,你需要先完成课程1
。
请你判断是否可能完成所有课程的学习?如果可以,返回 true
;否则,返回 false
。
示例 1:
输入:numCourses = 2, prerequisites = [[1,0]] 输出:true 解释:总共有 2 门课程。学习课程 1 之前,你需要完成课程 0 。这是可能的。
示例 2:
输入:numCourses = 2, prerequisites = [[1,0],[0,1]] 输出:false 解释:总共有 2 门课程。学习课程 1 之前,你需要先完成课程 0 ;并且学习课程 0 之前,你还应先完成课程 1 。这是不可能的。
思路一:拓扑排序
c++解法
class Solution {
public:
vector<vector<int>> g;
vector<int> d;
int n;
int cnt;
bool topSort()
{
queue<int> q;
for(int i = 0;i < n;i ++)
{
if(d[i] == 0) q.push(i);
}
while(!q.empty())
{
int t = q.front();
q.pop();
cnt ++;
for(int i = 0;i < g[t].size();i ++)
{
int j = g[t][i];
if( --d[j] == 0) q.push(j);
}
}
return cnt == n;
}
bool canFinish(int numCourses, vector<vector<int>>& prerequisites) {
g.resize(numCourses);
d.resize(numCourses);
n = numCourses;
for(vector<int> prerequisity : prerequisites)
{
g[prerequisity[1]].push_back(prerequisity[0]);
d[prerequisity[0]]++;
}
return topSort();
}
};
分析:
本题为经典的拓扑排序例题,每个课程需先完成先导课程才能进行下一步的学习,利用拓扑排序创建队列,利用队列先进先出的特性,先将入度为零的点放入队列,利用bfs广度遍历后将入度不为零的点降低入度后放入队列,若最后队列中数少于原课程数则返回false,反之返回true
总结:
本题考察对拓扑排序的应用,利用队列存放入度为零的数(即可学习的课程),最后比较队列中数和总数是否相等即可解决