课程表 II

题目链接

课程表 II

题目描述

课程表 II_第1张图片

注意点

  • 所有[ai, bi] 互不相同
  • ai != bi
  • 可能会有多个正确的顺序,只要返回 任意一种
  • 如果不可能完成所有课程,返回 一个空数组

解答思路

  • 此题与课程表类似,区别在于需要将学习课程的顺序输出
  • 还是相同的思路,需要先统计出每个课程需要学习的前置课程数量以及每个课程学习影响的相关课程列表,然后广度优先遍历不断统计出无前置课程或前置课程已经全部学完的课程,直到没有能够学习的课程为止

代码

class Solution {
    public int[] findOrder(int numCourses, int[][] prerequisites) {
        int[] res = new int[numCourses];
        // 当前学习的课程数
        int studyNum = 0;
        // penetration[i]表示课程i的前置课程数量
        int[] preCouseNumArr = new int[numCourses];
        // preCourses.get(i)表示需要先学习课程i影响的相关课程
        List<List<Integer>> edge = new ArrayList<>(numCourses);
        for (int i = 0; i < numCourses; i++) {
            edge.add(new ArrayList<>());
        }
        for (int[] prerequisite : prerequisites) {
            edge.get(prerequisite[1]).add(prerequisite[0]);
            preCouseNumArr[prerequisite[0]]++;
        }
        // 存储当前入度为0的课程
        Deque<Integer> deuqe = new ArrayDeque<>();
        for (int i = 0; i < numCourses; i++) {
            if (preCouseNumArr[i] == 0) {
                deuqe.addLast(i);
            }
        }
        while (!deuqe.isEmpty()) {
            int preCourse = deuqe.pollFirst();
            res[studyNum] = preCourse;
            studyNum++;
            for (int nextCourse : edge.get(preCourse)) {
                preCouseNumArr[nextCourse]--;
                if (preCouseNumArr[nextCourse] == 0) {
                    deuqe.addLast(nextCourse);
                }
            }
        }
        if (studyNum < numCourses) {
            return new int[0];
        }
        return res;
    }
}

关键点

  • 拓扑排序的思想
  • 广度优先遍历的思想

你可能感兴趣的:(算法,数据结构,leetcode,算法,java)