课程表 II

题目链接

课程表 II

题目描述

注意点

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

解答思路

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

代码

class Solution {
    public int[] findOrder(int numCourses, int[][] prerequisites) {
        int[] res = new int[numCourses];
        // 第i门课程有多少先修课程->入度
        int[] courses = new int[numCourses];
        // 第i门课程有多少后修课程->出度
        Map<Integer, List<Integer>> map = new HashMap<>();
        for (int[] prerequisite : prerequisites) {
            int course0 = prerequisite[0];
            int course1 = prerequisite[1];
            courses[course0]++;
            List<Integer> list = map.get(course1);
            if (list == null) {
                list = new ArrayList<>();
                map.put(course1, list);
            }
            list.add(course0);
        }
        int idx = 0;
        Deque<Integer> dq = new ArrayDeque<>();
        for (int i = 0; i < numCourses; i++) {
            if (courses[i] == 0) {
                res[idx] = i;
                idx++;
                dq.offer(i);
            }
        }
        while (!dq.isEmpty()) {
            // course0已学习,其相应后修课程的入度减1
            int course0 = dq.poll();
            List<Integer> list = map.get(course0);
            if (list == null || list.size() == 0) {
                continue;
            }
            for (int course1 : list) {
                courses[course1]--;
                if (courses[course1] == 0) {
                    res[idx] = course1;
                    idx++;
                    dq.offer(course1);
                }
            }
        }
        return idx == numCourses ? res : new int[0];
    }
}

关键点

  • 拓扑排序的思想
  • 广度优先遍历的思想
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值