賽馬娘今日份美圖
阿新 • • 發佈:2022-03-31
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; };