week13-leetcode #210-Course-Schedule-II

来源:互联网 发布:二次元网站源码 编辑:程序博客网 时间:2024/09/21 09:29

week13-leetcode #210-Course-Schedule-II

链接:https://leetcode.com/problems/course-schedule-ii/description/

Question

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, 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.

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:

  • 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.

Solution

class Solution {public:  vector<int> findOrder(int n, vector<pair<int, int > >& edges) {    vector<int> result;    vector<int> degree(n, 0);    int edges_size = edges.size();    vector<vector<bool > > edgeMatrix(n, vector<bool>(n, 0));    for (int i = 0; i < edges_size; i++) {      // cout << "edges[i].second" << edges[i].second << endl;      degree[edges[i].second]++;      edgeMatrix[edges[i].first][edges[i].second] = 1;    }    // for (int i = 0; i < n; i++) {    //   cout << degree[i] << " ";    // }    // cout << endl;    queue<int> my_queue;    bool no_result = false;    while (true) {      for (int i = 0; i < n; i++) {        if (degree[i] == 0) {          result.push_back(i);          my_queue.push(i);        }      }      if (my_queue.empty()) {        for (int i = 0; i < n; i++) {          if (degree[i] != -1) {            // cout << "i: " << i << endl;            // cout << degree[i] << endl;            no_result = true;            break;          }        }        break;      }      while (!my_queue.empty()) {        int first_node = my_queue.front();        my_queue.pop();        for (int i = 0; i < n; i++) {          if (edgeMatrix[first_node][i]) {            // cout << "first_node: " << first_node << endl;            // cout << "i: " << i << endl;            degree[i]--;            // cout << degree[i] << endl;          }        }        degree[first_node] = -1;      }    }    if (no_result) return vector<int>();    reverse(result.begin(), result.end());    return result;  }};

思路:这道选择课程的题目实际上是关于拓扑排序的问题。对于拓扑排序,遍历一边所有边计算每个节点的入度,将入度为0的节点push入队列中。每次pop队首的节点,相当于在图中删除节点。一直循环直到图为空或者是图不再变化。如果图为空则说明存在一个个拓扑序列,否则不存在满足条件的拓扑序列。