LeetCode 210. Course Schedule II

来源:互联网 发布:大数据职位 编辑:程序博客网 时间:2024/05/22 04:58

ladys and gentleman,又到了令人激动的一周更新时刻,这周我们的主题是拓扑排序,关于拓扑排序请自行度娘,本来昨晚就可以更完的,然而五月天的演唱会吵到我无法思考,甚至短路了,导致昨晚写了一晚上,调了不知道多久的bug,还是没有做出来,后来在床上稍稍冷静一下才发现自己真的是有毒。第一次觉得演唱会真的很烦。我就是身在福中不知福你咬我啊~~~不过是真的很吵。

好了,我们回到正题,拓扑排序其实是很简单的,我们老师介绍了两种方法来实现,第一种是最简单易想的,也是实现比较直接的,首先,你需要一个邻接矩阵或者邻接表,然后遍历找到所有入度为0的点,输出并将从这个点出发的边全部去掉,重复此过程,如果最后有点剩余就无法完成拓扑排序。另外一种方法实现起来也不难,但没那么好懂,大概意思就是先建一棵深度优先搜索树,并标记一下每个点的post值和pre值,这两个值就是这个点第一次到达的时刻以及最后一次到达的时刻,最后只要按照post值的逆序输出就是最后的拓扑排序了。

由于第二种方法我掌握得还不是那么好,所以我这里就选择了第一种方法。

----------------------------下面是题目----------------------------------------

There are a total of n courses you have to take, labeled from 0 ton - 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, return the ordering of courses you should take to finish all courses.

There may be multiple correct orders, you just need to return one of them. If it is impossible to finish all courses, return an empty array.

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 the correct course order is[0,1]

4, [[1,0],[2,0],[3,1],[3,2]]

There are a total of 4 courses to take. To take course 3 you should have finished both courses 1 and 2. Both courses 1 and 2 should be taken after you finished course 0. So one correct course order is[0,1,2,3]. Another correct ordering is[0,2,1,3].

Note:

  1. The input prerequisites is a graph represented by a list of edges, not adjacency matrices. Read more abouthow a graph is represented.
  2. You may assume that there are no duplicate edges in the input prerequisites.
-----------------------------下面是题解-------------------------------

题解我就不想说太多了,原理大家都懂,首先建邻接矩阵,然后按照上面说的方法做就好了。

直接上代码

#include <iostream>#include <map>#include <vector> #include <string>#include <queue>#include <memory.h>using namespace std;class Solution {public:    vector<int> findOrder(int numCourses, vector<pair<int, int> >& prerequisites) {        bool a[2010][2010];//邻接矩阵,这两个大小是一个一个试出来的        memset(a,0,sizeof(a));        bool visited[2010];//判断是否被访问过
        int in[2010];//入度的数组,这样就不用每次都访问整列才能知道入度是不是为0了        memset(in,0,sizeof(in));        memset(visited,0,sizeof(visited));
int num=prerequisites.size(); for(int i=0;i<num;i++) { a[prerequisites[i].first][prerequisites[i].second]=1; in[prerequisites[i].first]++;}//构建邻接矩阵,顺便把入度的数组做好。vector<int> ans;for(int k=0;k<numCourses;k++){for(int i=0;i<numCourses;i++){if(in[i]==0&&visited[i]==0){ans.push_back(i);visited[i]=1;for(int j=0;j<numCourses;j++){if(a[j][i]==1){a[j][i]=0;in[j]--;} } }}}//这就是拓扑排序了,这一部分是可以优化的,但是我懒啊,为了省事就直接选择了重复扫描n次来确定没有漏网之鱼了if(ans.size() <numCourses){vector<int> empty;return empty;}//如果不是所有点都在里面的话就判断不能全部完成return ans;}};


------------------------------------分割线----------------------------------

是不是很简单了,然而昨天的我就是有毒,我决定将这个锅甩到五月天身上。恩,就是这样。

see you next illusion




2 0