一、题目
来源:力扣https://leetcode.cn/problems/course-schedule/
二、前提引入
关于拓扑排序问题,在数据结构算法书中,提到了邻接表,邻接数组的方法。
对于先学什么课随后学什么课,我们可以通过图在这个数据结构展现。构造有向图。
三、解题思路
1、题中所谓“选了1,随后学0” 与 “选了0 随后学1”矛盾,意在表示:这是一个有向无环图。只要
保证这一点,return true即可。
2、利用邻接数组,将一门课后面紧跟的课程全部连接到该课后面。形成:一门课序号对应一个数
组。那么,如何在不使用类的情况下将而这进行绑定呢:使用unordered_map函数,进行键值对
绑定。
unordered_map<int, vector<int>>map; // 邻接数组
unordered_map<int, int>ru; // 入度和课程绑定
3、利用BFS,本质上使用了队列,将入度为0的课程入队列,随后将所有紧跟在这门课后面的课程
入度-1,倘若最后,剩下的课程均入度不为0,那么肯定出现了环。return false。
while (!qres.empty()){
int qq = qres.front();
qres.pop();
count++;
for (int i = 0; i < map[qq].size(); i++){
if (!(--ru[map[qq][i]])) qres.push(map[qq][i]);
}
if (count == numCourses) return true;
}
return false;
4、既然涉及到了图,必然有入度和出度。那么,在入度为0的课程退出队列之后,他指向的那些课
程入度-1,为了更好的区分那些课程的入度数值,因此也需要课程序号和入度数值绑定,方便进行
判断。并且可以及时对入度为0的课程加入队列。
四、代码
bool canFinish(int numCourses, vector<vector<int>>& prerequisites) {
unordered_map<int, vector<int>>map; // 邻接数组
unordered_map<int, int>ru; // 入度
int count = 0;
for (int i = 0; i < numCourses; i++) ru[i] = 0;
for (int i = 0; i < prerequisites.size(); i++){
map[prerequisites[i][1]].push_back(prerequisites[i][0]);
ru[prerequisites[i][0]]++;
}
queue<int>qres;
for (int i = 0; i < numCourses; i++) if (!ru[i]) qres.push(i);
while (!qres.empty()){
int qq = qres.front();
qres.pop();
count++;
for (int i = 0; i < map[qq].size(); i++){
if (!(--ru[map[qq][i]])) qres.push(map[qq][i]);
}
if (count == numCourses) return true;
}
return false;
}