现在你总共有 n 门课需要选,记为 0 到 n-1。
在选修某些课程之前需要一些先修课程。 例如,想要学习课程 0 ,你需要先完成课程 1 ,我们用一个匹配来表示他们: [0,1]
思想:也就是各个课程的选择具有偏序关系,构成一个有向图,要使按偏向关系完成所有课程要求此有向图无环,所以利用拓扑排序
时间复杂度O(||vertex||^2),空间复杂度O(||vertex||)
class Solution {public int[] findOrder(int numCourses, int[][] prerequisites) {//先构照邻接表<v1,List>//list表示为v1所指向的节点,或者说v1和list构成了其边集HashMap<Integer,List<Integer>> adj = new HashMap<>();int[] edgsCount = new int[numCourses];//用于表示各个节点的入度List<Integer> res = new ArrayList<>();//用于存储课程节点的访问顺序//初始化邻接表for(int vid=0;vid<numCourses;vid++){adj.put(vid,new ArrayList<Integer>());}//基于偏向关系集prerequisites,再次初始化adj和edgesCountfor(int[]temp:prerequisites){adj.get(temp[1]).add(temp[0]);//temp[1]->temp[0]edgsCount[temp[0]]++;//temp[0]的入度+1}LinkedList<Integer> queue = new LinkedList<>();//构建一个队列进行拓扑排序,这里使用BFSfor(int vertex=0;vertex<numCourses;vertex++){//初始化队列,将入度为0的顶点入队if(edgsCount[vertex]==0){queue.add(vertex);}}//进行拓扑排序while(!queue.isEmpty()){int fromVertex = queue.poll();res.add(fromVertex);//遍历它的所有边,将其所指向的顶点的入度减1for(int toVertex:adj.get(fromVertex)){edgsCount[toVertex]--;if(edgsCount[toVertex]==0){//再次将入度为0的节点入队queue.add(toVertex);}}}if(res.size()==numCourses){//若拓扑排序完成后,所有节点均入队了,则表示此图无环,可以完成所有课程int[] t = new int[numCourses];for(int i=0;i<res.size();i++){t[i] = res.get(i);}return t; }return new int[0];}
}