演算法——課程表 II(有向圖拓撲排序)
阿新 • • 發佈:2021-01-10
現在你總共有 n 門課需要選,記為 0 到 n-1。
在選修某些課程之前需要一些先修課程。 例如,想要學習課程 0 ,你需要先完成課程 1 ,我們用一個匹配來表示他們: [0,1]
給定課程總量以及它們的先決條件,返回你為了學完所有課程所安排的學習順序。
可能會有多個正確的順序,你只要返回一種就可以了。如果不可能完成所有課程,返回一個空陣列。
leetcode
解題思路:這是是個有向圖的拓撲排序問題。如果圖中存在環,那麼就不能產生結果,需要返回空。
- 利用一個map來儲存圖,需要先學習的課程為出發點;
- 深搜每個節點,一條路中,最後搜到的點需要放在最後。
- 如果搜到了之前存在的節點,那麼就將失敗標記置位。
class Solution { Map<Integer, List<Integer>> map; boolean flag = true; int[] st; int[] res; int cnt; public int[] findOrder(int num, int[][] prerequisites) { map = new HashMap<>(); res = new int[num]; st = new int[num]; cnt = num - 1; for(int i = 0; i < num; i++) map.put(i, new ArrayList<>()); for(int[] p : prerequisites) map.get(p[1]).add(p[0]); for(int i = 0; i < num && flag; i++) { if(st[i] == 0) dfs(i); } if(flag) return res; return new int[0]; } public void dfs(int cur) { // 標記當前節點已經走過 st[cur] = 1; for(int v : map.get(cur)) { if(st[v] == 0) { // 如果點沒有被搜過 dfs(v); if(!flag) return; }else if(st[v] == 1) { // 如果搜到了走過的點,說明存在環 flag = false; return; } } // 標記當前點已經完成搜尋,不在環上 st[cur] = 2; res[cnt --] = cur; } }