依旧还是有关于图的题目,这次不一样的点在于题目并没有明确的给出他是图的题目的形式,而是说让你根据其题目意思来进行操作。
首先,就是搞清楚题目的意思。假设你想学习A课程,那就是必须先学习B课程,但是这里给出的例子只有两个,我们要知道的是不一定只有B课程,可能还有其他的比如说C、D课程,要把这些都学完了你猜可以学A,同时A也可能成为某种课程的充分条件,那么这里我们就可以知道这就是图类题目的形式。
然后需要注意的是,题目给出的numCourse就是所有课程的种树,那我们就可以通过设置一个计时器,来记录有学某种课程的总数量,最后比较,若相等则返回true,反之返回false。
具体来实现的话,步骤如下:
- 需要一个一维数组来记录每个课程的入度,代码中是 inDegree
- 还需要一个map集合来记录各个结点之间的关系
- 首先需要遍历,用以记录每个课程的入度,以及他们之间的关系
- 然后将所有入度为0的课程存放入队列中
- 接着我们开始学了,学习该课程之后便需要更新其入度的数量,所以需要这个操作
最后完整的代码如下,我也是参考力扣上面其他的大神的,一起加油吧!
class Solution {
public:
bool canFinish(int numCourses, vector<vector<int>>& prerequisites) {
vector<int> inDegree(numCourses); // 记录每个结点的入度
unordered_map<int, vector<int>> map; // 记录每个结点之间的关系
// 遍历记录每个结点的入度并建立关系
for( int i = 0; i < prerequisites.size(); i++){
inDegree[prerequisites[i][0]]++;
map[prerequisites[i][1]].push_back(prerequisites[i][0]);
}
// 定义队列+bfs
queue<int> que;
// 遍历入度为0的课
for(int i = 0; i < numCourses; i++){
if(inDegree[i] == 0) que.push(i); // 课程是用数字来表示的,所以说不影响
}
int count = 0;
while (que.size()){
int selected=que.front();
que.pop();
count++;
//更新所有关联结点的入度
for (int i = 0; i < map[selected].size(); i++){
if(inDegree[map[selected][i]] > 0){
inDegree[map[selected][i]]--;
if(inDegree[map[selected][i]] == 0){
que.push(map[selected][i]); // 将入度为0的课程放到队列中
}
}
}
}
if(count==numCourses)
return true;
else
return false;
}
};