1. 概念
拓撲排序:對於n個節點的有向圖G,一個有向邊(u, v),那么對節點進行排序后,u在v的前面(如果G中有環存在,那么不能進行拓撲排序)。
可以用dfs(棧)和bfs(隊列)來實現拓撲排序。
dfs具體算法:將所有的點設為三種狀態:未搜索0,搜索中1,已完成2。對任意一個未搜索節點0的相鄰節點進行搜索,同時把這個節點的狀態設為1,1的相鄰節點只能是0和2,如果狀態為1的節點的相鄰節點狀態為1,說明有環,返回null。如果沒有相鄰節點,保存到棧中,把這個節點的狀態設為2。
2. 代碼
class Solution { // 存儲有向圖 List<List<Integer>> map; // 用一個數組來模擬棧 int[] result; int index; // 保存每一個節點的訪問狀態 int[] visited; // 如果有環存在,valid=false boolean valid; public int[] findOrder(int numCourses, int[][] prerequisites) { map = new ArrayList<>(); result = new int[numCourses]; index = numCourses; visited = new int[numCourses]; valid = true; for(int i = 0; i < numCourses; i++){ map.add(new ArrayList<>()); } for(int[] edge : prerequisites){ //構建有向圖 map.get(edge[1]).add(edge[0]); } for(int i = 0; i < numCourses && valid; i++){ if(visited[i] == 0){ dfs(i); } } //說明有環 if(!valid){return new int[]{};} return result; } public void dfs(int u){ visited[u] = 1; for(int v : map.get(u)){ if(visited[v] == 1){ valid = false; return; }else if(visited[v] == 0){ dfs(v); } } visited[u] = 2; //存儲到棧中 result[--index] = u; } }