题目原网址为https://leetcode.com/problems/course-schedule/description/
一.题目
There are a total of n courses you have to take, labeled from 0
to n - 1
.
Some courses may have prerequisites, for example to take course 0 you have to first take course 1, which is expressed as a pair: [0,1]
Given the total number of courses and a list of prerequisite pairs, is it possible for you to finish all courses?
For example:
2, [[1,0]]
There are a total of 2 courses to take. To take course 1 you should have finished course 0. So it is possible.
2, [[1,0],[0,1]]
There are a total of 2 courses to take. To take course 1 you should have finished course 0, and to take course 0 you should also have finished course 1. So it is impossible.
Note:
- The input prerequisites is a graph represented by a list of edges, not adjacency matrices. Read more about how a graph is represented.
- You may assume that there are no duplicate edges in the input prerequisites.
二.我的解法
class Solution {
public:
bool canFinish(int numCourses, vector<pair<int, int>>& prerequisites) {
vector<list<int>> graph(numCourses);
for (int i = 0; i < prerequisites.size(); i++) {
graph[prerequisites[i].second].push_back(prerequisites[i].first);
}
queue<int> source;
vector<int> degree(numCourses);
for (int i = 0; i < prerequisites.size(); i++) {
degree[prerequisites[i].first]++;
}
for (int i = 0; i < numCourses; i++) {
if (!degree[i]) {
source.push(i);
}
}
while (!source.empty()) {
int course = source.front();
source.pop();
for (auto i = graph[course].begin(); i != graph[course].end(); i++) {
degree[*i]--;
if (!degree[*i]) {
source.push(*i);
}
}
}
for (int i = 0; i < numCourses; i++) {
if (degree[i] > 0) {
return false;
}
}
return true;
}
};
三.解法分析
把每一个课程看做一个节点,如果课程a要先于课程b上,那么有一条a到b的有向边,那么这个问题就可以变成判断图是否有环的问题,这里我用了
拓扑排序来判读图是否有环,如果可以完成拓扑排序,那么就没有环,否则就有。我这里拓扑排序的实现思路如下:
就是每次选取入度为0的点从图上去掉,假设为点a,那么所有的点b满足a到b有边的点入度减一,如此不断地进行下去,如果所有的点都从图中删去,
那么图就没有环,否则就有环