题目:https://leetcode-cn.com/problems/course-schedule/submissions/
代码:
class Solution {
public:
bool canFinish(int numCourses, vector<vector<int>>& prerequisites) {
vector<vector<int>>G(numCourses);
vector<int>degree(numCourses, 0);
stack<int>S;
int count = 0;
//构建图的邻接表(有向图)
for(int i = 0;i < prerequisites.size();i++)
G[prerequisites[i][0]].push_back(prerequisites[i][1]);
//存储每一个节点的入度
for(int i = 0;i < prerequisites.size();i++)
degree[prerequisites[i][1]]++;
//入度为0的节点放入栈中,并且用count计数
//count用于计数出栈的节点
for(int i = 0;i < numCourses;i++)
if(degree[i] == 0){
S.push(i);
count++;
}
while(!S.empty()){
int index = S.top();
//每一次出栈都需要将该节点所指节点产生的入度减一
S.pop();
for(int i = 0;i < G[index].size();i++){
degree[G[index][i]]--;
//减完之后继续判断入度为0的节点
if(degree[G[index][i]] == 0){
S.push(G[index][i]);
count++;
}
}
}
//如果拓扑排序产生的节点为numCourses个则证明全部出栈完成。
if(count == numCourses) return true;
return false;
}
};
思路:这题是很明显的拓扑排序思路,先修课程修完之后才可以进行后修课程,将这个关系看成一个有向图,当一个课程没有先修课或者先修课修完之后才可以进行学习。即是一个有向图中节点是否有入度,如果入度为0那么这个课程就可以进行学习。