提示中说了关键点在于求图中是否存在环的问题,典型的拓扑排序。有关拓扑排序的问题可以参考这篇文章点击打开链接 。图的数据结构有邻接表和邻接矩阵,选择邻接表可以很好的表明结点之间的依赖关系。
判断图是否可以拓扑排序,我们可以每次找到入度为0的结点,然后删除与该结点连接的边,也就是相邻节点的入度减1,直到所有结点遍历完成。如果不存在入度为0的结点(存在环路),则返回false.
class Solution {
public:
bool canFinish(int numCourses, vector<pair<int, int>>& prerequisites) {
vector<unordered_set<int>> posts;
for(int i=0;i<numCourses;i++){
unordered_set<int> set;
posts.push_back(set);
}
for(int i=0;i<prerequisites.size();i++){
posts[prerequisites[i].second].insert(prerequisites[i].first);
}
int preNums[numCourses]={0};//局部数组初始化很重要,不然会WA
//考虑到数据pair中可能有重复,所以在不能在上一个循环中加入preNums[prerequisites[i].first]++,而应该用如下循环
for(int i=0;i<numCourses;i++){
for(auto it = posts[i].begin();it !=posts[i].end();++it){
preNums[*it]++;
}
}
for(int i=0;i<numCourses;i++){
int j=0;
for(;j<numCourses;j++){
if(preNums[j]==0)break;
}
if(j==numCourses)return false;
preNums[j]=-1;
for(auto it = posts[j].begin();it !=posts[j].end();++it){
preNums[*it]--;
}
}
return true;
}
};