1. 程式人生 > 遊戲資訊 >【明日方舟】100張高質量能天使美圖、桌布、風景圖分享第一回 #117

【明日方舟】100張高質量能天使美圖、桌布、風景圖分享第一回 #117

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;
};