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?
Example 1:
Input: 2, [[1,0]]
Output: true
Explanation: There are a total of 2 courses to take.
To take course 1 you should have finished course 0. So it is possible.
Example 2:
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.
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.
分析
题目的意思是:给定课程的数量,以及课程修的时候需要先修的课程。题目问能够修完所有的课程。
- 问题是本质上判断有向图是否有环,解题过程本质上是一个拓扑排序的过程,拓扑排序序言先构建图,然后用队列来辅助完成。
C++代码
class Solution {
public:
bool canFinish(int numCourses, vector<pair<int, int>>& prerequisites) {
vector<vector<int>> graph(numCourses,vector<int>(0));
vector<int> inDegree(numCourses,0);
for(auto k:prerequisites){
graph[k.second].push_back(k.first);
inDegree[k.first]++;
}
queue<int> que;
for(int i=0;i<numCourses;i++){
if(inDegree[i]==0){
que.push(i);
}
}
while(!que.empty()){
int u=que.front();
que.pop();
for(auto v:graph[u]){
inDegree[v]--;
if(inDegree[v]==0){
que.push(v);
}
}
}
for(int i=0;i<numCourses;i++){
if(inDegree[i]!=0){
return false;
}
}
return true;
}
};
Python实现
把课程表构造成一个有向图,然后使用拓扑排序解决即可,其中队列q记录的是图的起始节点,按顺序遍历这些起始节点,最后检查每个节点的入度是否为0来判断是否满足要求。
class Solution:
def canFinish(self, numCourses: int, prerequisites: List[List[int]]) -> bool:
# topological sort
graph = defaultdict(list)
indegree=defaultdict(int)
for pre in prerequisites:
graph[pre[1]].append(pre[0])
indegree[pre[0]]+=1
q = deque()
for i in range(numCourses):
if indegree[i]==0:
q.append(i)
while q:
u = q.popleft()
for v in graph[u]:
indegree[v]-=1
if indegree[v]==0:
q.append(v)
for i in range(numCourses):
if indegree[i]!=0:
return False
return True