剑指 Offer II 113. 课程顺序

Posted 易小顺

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了剑指 Offer II 113. 课程顺序相关的知识,希望对你有一定的参考价值。

算法记录

LeetCode 题目:

  给定一个数组 prerequisites ,它的每一个元素 prerequisites[i] 表示两门课程之间的先修顺序。 例如 prerequisites[i] = [ai, bi] 表示想要学习课程 ai ,需要先完成课程 bi 。


思路


说明

一、题目

  请根据给出的总课程数 numCourses 和表示先修顺序的 prerequisites 得出一个可行的修课序列。
  可能会有多个正确的顺序,只要任意返回一种就可以了。如果不可能完成所有课程,返回一个空数组。

二、分析

  • 分析题意可知就是一个拓扑排序题,拓扑排序需要三个角色,一个入度用来确定是否可选择,一个邻接表用来确定节点出度方向,一个队列用来保存拓扑的序列。
  • 遍历初始关系数组来确定每个课程的入度信息和邻接表,如果入度为零也就说可以进行选择将用来初始化队列。
  • 只要队列不为空,就去取出课程添加到结果中,然后根据邻接表更新其他节点的入度信息,看是否能被添加到队列中进行选择。
  • 注意一个最后的选择条件,只要选择的课程数量不满足原始的课程数量即可认为没有这样的一个序列来完成课程的分配(这里是一个坑,错了好几遍)。
class Solution 
    public int[] findOrder(int numCourses, int[][] prerequisites) 
        int[] in = new int[numCourses];
        List<Integer> ret = new ArrayList();
        ArrayList<Integer>[] prefix = new ArrayList[numCourses];
        for(int i = 0; i < numCourses; i++)  prefix[i] = new ArrayList();
        for(int i = 0; i < prerequisites.length; i++) 
            in[prerequisites[i][0]]++;
            prefix[prerequisites[i][1]].add(prerequisites[i][0]);
        
        Queue<Integer> queue = new LinkedList();
        for(int i = 0; i < numCourses; i++) if(in[i] == 0) queue.add(i);
        while(!queue.isEmpty()) 
            int temp = queue.poll();
            ret.add(temp);
            for(int i : prefix[temp]) 
                in[i]--;
                if(in[i] == 0) queue.add(i);
            
        
        return ret.size() < numCourses ? new int[] : ret.stream().mapToInt(Integer::valueOf).toArray();
    


总结

熟悉拓扑排序的规则。

以上是关于剑指 Offer II 113. 课程顺序的主要内容,如果未能解决你的问题,请参考以下文章

剑指 Offer II 113. 课程顺序

剑指 Offer II 113. 课程顺序

剑指 Offer II 113. 课程顺序

剑指 Offer II 113. 课程顺序

剑指 Offer II 113. 课程顺序

剑指offer 65 至 剑指offer 68 - II 题解