LeetCode 210. 课程表 II

210. 课程表 II

解题思路:

解法一:

拓扑排序。先用vector建图,并统计每个节点的入度,找到入度为0的点,遍历整个图,在遍历完一个点要把与该点邻接的点的入度减一,找到下一个入度为0的点继续遍历。最后在查看是否所有的点的入度都为0,如果都为0返回答案,否则图中存在环路,返回空。

class Solution {
public:
    vector<int> findOrder(int numCourses, vector<vector<int>>& prerequisites) {
      vector<int> ans;
      vector<int> deg(numCourses);
      vector<vector<int>> edge(numCourses);
      for (const auto &vec : prerequisites) {
        ++deg[vec[1]];
        edge[vec[0]].push_back(vec[1]);
      }
      queue<int> q;
      for (int i = 0; i < numCourses; ++ i) {
        if (deg[i] == 0) q.push(i);
      }
      while(!q.empty()) {
        int val = q.front(); q.pop();
        ans.push_back(val);
        for (auto chil : edge[val]) {
          if (--deg[chil] == 0) {
            q.push(chil);
          }
        }
      }
      for (int i = 0; i < numCourses; ++ i) {
        if (deg[i] != 0) return {};
      }
      reverse(ans.begin(), ans.end());
      return ans;
    }
};

解法二:

DFS搜图+判环。用DFS来搜索图中每个点相邻的节点,同时注意判断环路。我们将当前正在搜索的点标记为1,还未搜索的点标记为0,搜索结束的点标记为2,如果正在搜索的点再次被搜索到说明图中存在环路。

//DFS搜图
class Solution {
public:
    void DFS(int node) {
      vis[node] = 1;  //将节点标记为搜索中,如果在搜索中在被搜索到说明有环
      for (auto chil : edge[node]) {
          if (vis[chil] == 0) {
            DFS(chil);
            if (!flag) return;
          }
          if (vis[chil] == 1) {
            flag = false;
            return;
          }
      }
      ans.push_back(node);
      vis[node] = 2;  //标记为搜索结束
      return;
    }
    vector<int> findOrder(int numCourses, vector<vector<int>>& prerequisites) {
      edge.resize(numCourses);
      vis.resize(numCourses);
      for (const auto &vec : prerequisites)
        edge[vec[0]].push_back(vec[1]);
      flag = true;
      for (int i = 0; i < numCourses; ++ i) {
        if (!vis[i]) DFS(i);
      }
      if (!flag) ans.clear();
      return ans;
    }
private:
  vector<vector<int>> edge;
  vector<int> ans;
  vector<int> vis;
  bool flag;
};

posted on 2022-04-08 15:17  翔鸽  阅读(18)  评论(0编辑  收藏  举报