[LeetCode] 207. Course Schedule

来源:互联网 发布:mac定制机 编辑:程序博客网 时间:2024/06/09 23:24

[LeetCode] 207. Course Schedule

题目描述

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.

分析

这道题和拓扑排序有关,一种方法是选择一个入度为0的点,并将这个点和这个点有关的边从图中去掉,然后重复这个过程。但是这个方法因为对每个点不断遍历边的集合,复杂度比较高,因此在提交时在测试数据为2000个课程的时候超时了。

class Solution {public:  bool canFinish(int numCourses, vector<pair<int, int>>& prerequisites) {    int *visited = new int[numCourses];    for (int i = 0; i < numCourses; i++) {      visited[i] = false;    }    vector<pair<int, int>> temp;    while (!prerequisites.empty()) {      int size = prerequisites.size();      for (int i = 0; i < numCourses; i++) {        temp = prerequisites;        int flag = false;        for (auto iter = prerequisites.begin(); iter != prerequisites.end(); ) {          if ((*iter).second == i) {            flag = true;            break;          } else if ((*iter).first == i) {            if (visited[(*iter).second]) return false;            iter = prerequisites.erase(iter);          } else {            iter++;          }        }        if (flag) {          prerequisites = temp;        }      }      if (prerequisites.size() == size) return false;    }    return true;  }};

要减少复杂度,那么需要减少遍历的过程,这里可以建立一个邻接表,并且维护一个统计入度为0的队列,每当有一个入度为0的点时就把这个点去掉,同时也把它指向的边也去掉,最后如果没有点则可以完成,有则不能完成。

class Solution {  public:    bool canFinish(int numCourses, vector<pair<int, int>>& prerequisites) {      vector<vector<int> > graph(numCourses, vector<int>(0));      vector<int> in(numCourses, 0);      for (auto p : prerequisites) {        graph[p.second].push_back(p.first);        in[p.first]++;      }      queue<int> q;      int count = 0;      for (int i = 0; i < numCourses; i++) {        if (in[i] == 0) {          q.push(i);          count++;        }      }      while (!q.empty()) {        int temp = q.front();        q.pop();        int size = graph[temp].size();        for (int j = 0; j < size; j++) {          in[graph[temp][j]]--;          if (in[graph[temp][j]] == 0) {            q.push(graph[temp][j]);            count++;          }        }      }      return count == numCourses;    }};