LeetCode210. 課程表 II
阿新 • • 發佈:2020-08-13
這題和LeetCode207. 課程表一樣,都是拓撲排序的模板題,只不過207題只需判斷是否存在拓撲序列,
這題要返回拓撲序列。
只需要在BFS時在一個結果陣列中記錄每個入隊的元素即可,最後判斷陣列大小是否和課程總數量numCourses相同,相同就返回我們記錄的所有元素的入隊順序的陣列res,
不相同就返回空陣列。
關於拓撲排序,可以看一下上面那個連結裡(207題)的步驟,207題搞定了,這題就稍微改一下就可以了。
程式碼如下:
class Solution { public: vector<int> findOrder(int numCourses, vector<vector<int>>& prerequisites) { vector<vector<int>> g(numCourses); //g表示課程關係之間的圖,g[i]陣列存放課程i的所有後繼課程 vector<int> inDegree(numCourses); //inDegree[i]表示課程i的入度(先修課程的數量) for(int i = 0; i < prerequisites.size(); ++i) { int course1 = prerequisites[i][0], course2 = prerequisites[i][1]; //這題的輸入比較奇怪,prerequisties的第一門課是後繼課程,第二門課才是先修課程,注意一下順序 g[course2].push_back(course1); //course2是course1的先修課程 ++inDegree[course1]; //course1的先修課程數量加一 } vector<int> res; //存放拓撲序列 queue<int> q; for(int i = 0; i < numCourses; ++i) { //拓撲排序最開始把所有入度為0的節點入隊 if(inDegree[i] == 0) { q.push(i); } } while(q.size()) { int curCourse = q.front(); //隊頭元素出隊,表示這門課程學完了 q.pop(); res.push_back(curCourse); for(int i = 0; i < g[curCourse].size(); ++i) { //這門學習完的課程的所有後繼課程的入度(先修課程數量)可以減一了 --inDegree[g[curCourse][i]]; if(inDegree[g[curCourse][i]] == 0) { //如果入度減一之後為0,則入隊 q.push(g[curCourse][i]); } } } if(res.size() != numCourses) { //無法學習完所有課程,返回空陣列 return {}; } return res; //存在一種包含所有課程的拓撲序列,則返回 } };