您的位置:首页 > 其它

207. Course Schedule

2016-09-14 00:34 246 查看
先上题目:

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.

这道题实际上就是要判断一个图里面是否存在有向环,如果存在,那么这个环中的每一门课程都需要先完成上一门课程才能学习,显然这是不可能完成的。要判断一个图里是否存在有向环,就要用拓扑排序算法进行判断。

在写这道题的时候,并没有使用邻接矩阵或者邻接表来表示一个图,直接用了很多个动态数组来表示每一个顶点的属性,比如入度(inDe)、出度(outDe)、是否被访问过(visited)。而数组idx表示将prerequisites的元素进行排序后,每个顶点的起始坐标,比如样例为(已排序):(0,1), (0,2), (1,3), (1,5), (3,4), (3,0), (4,5), (5,1), (5,3),那么idx[0] = 0, idx[1]
= 2, idx[3] = 4, idx[4] = 6, idx[5] = 7,而idx[2]并没有被赋值,因为它的出度为0。

拓扑排序就是先搜寻入度为0的点,然后删掉该点和与之关联的边,并更新各个点的入度,再寻找一个新的入度为0的点,如此反复,直到所有点都被遍历或者再也找不到入度为0的新点为止。按照我的代码时间复杂度应该是O(n^2+e),然而如果用栈来储存入度为0的顶点的话,那么就不需要每次都遍历所有点来寻找入度为0的顶点,这样时间复杂度就降为O(n+e)。

#include <iostream>
#include <algorithm>
#include <vector>
#include <utility>
using namespace std;

bool operator <(pair<int, int> a, pair<int, int> b) {
if (a.first < b.first) return true;
else return false;
}

class Solution {
public:
bool canFinish(int numCourses, vector<pair<int, int>>& prerequisites) {
sort(prerequisites.begin(), prerequisites.end());
bool res = true;
bool *visited = new bool[numCourses];
int numVisited = 0;
for (int i = 0; i < numCourses; i++) visited[i] = false;
int *inDe = new int[numCourses];
int *outDe = new int[numCourses];
int *idx = new int[numCourses];
idx[0] = 0;
for (int i = 0; i < numCourses; i++) {
inDe[i] = 0;
outDe[i] = 0;
}
for (int i = 0; i < prerequisites.size(); i++) {
inDe[prerequisites[i].second]++;
outDe[prerequisites[i].first]++;
if (i != 0 && prerequisites[i].first != prerequisites[i - 1].first) {
idx[prerequisites[i].first] = i;
}
}
while (numVisited != numCourses && res) {
res = false;
int node;
for (int i = 0; i < numCourses; i++) {
if (inDe[i] == 0 && !visited[i]) {
res = true;
numVisited++;
visited[i] = true;
node = i;
break;
}
}
if (res)
for (int i = 0; i < outDe[node]; i++) {
inDe[prerequisites[idx[node] + i].second]--;
}
}
return res;
}
};

然而不知道为什么不能通过Leetcode的检测,它提示我Wrong Answer的样例我放在Runcode里执行的结果是正确的,按照官网的说法,我的代码可能存在bug使得连续测试多个样例(也就是Submit的时候)会出现问题,而测试单个样例(Runcode的时候)是没有问题的,但是我也不知道哪里有bug
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: