207. 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?
Difficulty:Medium
Example:
Input: 2, [[1,0],[0,1]]
Output: false
Explanation: 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.
方法1:拓扑排序,深度搜索
- Time complexity : O ( ) O\left (\right ) O()
- Space complexity :
O
(
)
O\left ( \right )
O()
思路:
建图,以及配套的出度,找出度为0的节点,没有之间返回false,有的话置为-1,并将其上游的出度都减1,再次寻找出度为0的节点,如果到最后都没有返回false,此时返回true。
class Solution {
public:
bool canFinish(int numCourses, vector<pair<int, int>>& prerequisites) {
vector<unordered_set<int>> graph(numCourses);
vector<int> degrees(numCourses, 0);
for(auto p : prerequisites){
graph[p.second].insert(p.first);
degrees[p.first]++;
}
for(int i = 0; i < numCourses; i++){
int j = 0;
for(; j < numCourses; j++)
if(!degrees[j]) break;
degrees[j] = -1;
if(j == numCourses) return false;
for(auto n : graph[j])
degrees[n]--;
}
return true;
}
};
方法2:拓扑排序,队列
- Time complexity : O ( ) O\left (\right ) O()
- Space complexity :
O
(
)
O\left ( \right )
O()
思路:
建图,以及配套的出度,找出度为0的节点,将其push到队列中,如果没有就返回false,将其上游的出度减1,如果上游的出度为0再将其push进去,并将此节点pop出去。
class Solution {
public:
bool canFinish(int numCourses, vector<pair<int, int>>& prerequisites) {
vector<unordered_set<int>> graph(numCourses);
vector<int> degrees(numCourses, 0);
for(auto p : prerequisites){
graph[p.second].insert(p.first);
degrees[p.first]++;
}
queue<int> Q;
for(int i = 0;i < numCourses;i++)
if(degrees[i] == 0)
Q.push(i);
int counter = 0;
while(!Q.empty())
{
int u = Q.front();
Q.pop();
++counter;
for(auto v : graph[u])
{
if(--degrees[v] == 0)
Q.push(v);
}
}
return counter == numCourses;
}
};