题目:
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.
难度:Medium
解题思路:看到题目很容易想到拓扑排序。 也可以把每门课程当成一个点,然后构造出一个图,每门课和它的“前提课程”之间有一条边,如果图中有回路的话,就说明这种情况是不可能排出合理的课程的。 比如说A的先导课程是B,B的先导课程又是A,A和B之间就产生了一条回路,这样无论是先学A还是先学B都无法满足条件。 那么我们要做的就是构造完图以后,判断图中是否有回路。 可以用深度优先的方法,对每门课进行深度优先遍历,访问过的课程标记一下,如果在这门课的深度优先遍历当中又访问到了已经访问过的课程,就说明有回路了,可以判断无法排课。 如果没有回路就说明这些课程是可以排课的。 我用了一个二维向量来表示这个图,对于每个点(课程),把它的先导课程加入到到它的向量中。比如: graph[0][0]=1,graph[0][1]=2就是说0号课程的先导课程有1号课程和2号课程。
class Solution {
public:
bool dfs(vector<vector<int> >& graph,bool book[],int cur)
{
book[cur]=true;
for(int i =0;i<graph[cur].size();i++)
{
int y=graph[cur][i];
if(book[y]==true)
{
return false;
}
return dfs(graph,book,y);
}
return true;
}
bool canFinish(int numCourses, vector<pair<int, int>>& prerequisites) {
vector< vector<int>> graph(numCourses+1);
for(int i =0;i<prerequisites.size();i++)
{
int x=prerequisites[i].first;
int y=prerequisites[i].second;
graph[x].push_back(y);
}
for(int i = 0;i<prerequisites.size();i++)
{
bool book[numCourses+1];
memset(book,false,sizeof(book));
if(book[prerequisites[i].first]==false)
{
book[prerequisites[i].first]=true;
if(dfs(graph,book,prerequisites[i].second)==false)
return false;
}
}
return true;
}
};
时间复杂度为O(E^2) 其中 E=prerequisites.size()