/**
     * LeetCode 210. Course Schedule II
     *
     * @param numCourses    课程数
     * @param prerequisites 课程先修关系
     * @return 课程学习顺序
     */
    public int[] findOrder(int numCourses, int[][] prerequisites) {
        int[] path = new int[numCourses];
        List<Integer>[] graph = buildGraph(numCourses, prerequisites);
        // build indegree array
        int[] indegree = new int[numCourses];
        for (int i = 0; i < numCourses; i++) {
            List<Integer> list = graph[i];
            for (int to : list) {
                indegree[to]++;
            }
        }
 
        // add nodes that in degree equals 0
        Deque<Integer> deque = new LinkedList<>();
        for (int i = 0; i < numCourses; i++) {
            if (indegree[i] == 0) {
                deque.add(i);
            }
        }
 
        int count = 0;
        while (!deque.isEmpty()) {
            int curr = deque.pop();
            path[count] = curr;
            count++;
            for (int child : graph[curr]) {
                indegree[child]--;
                if (indegree[child] == 0) {
                    deque.add(child);
                }
            }
        }
 
        return count == numCourses ? path : new int[]{};
    }
 
    public List<Integer>[] buildGraph(int numCourses, int[][] prerequisites) {
        List<Integer>[] res = new LinkedList[numCourses];
        for (int i = 0; i < numCourses; i++) {
            res[i] = new LinkedList<>();
        }
        for (int[] pair : prerequisites) {
            res[pair[1]].add(pair[0]);
        }
        return res;
    }