面试算法113:课程顺序

发布时间:2024年01月11日

题目

n门课程的编号为0~n-1。输入一个数组prerequisites,它的每个元素prerequisites[i]表示两门课程的先修顺序。如果prerequisites[i]=[ai,bi],那么必须先修完bi才能修ai。请根据总课程数n和表示先修顺序的prerequisites得出一个可行的修课序列。如果有多个可行的修课序列,则输出任意一个可行的序列;如果没有可行的修课序列,则输出空序列。
例如,总共有4门课程,先修顺序prerequisites为[[1,0],[2,0],[3,1],[3,2]],一个可行的修课序列是0→2→1→3。

分析

先根据先修顺序构建出有向图graph,graph用一个HashMap表示邻接表,它的键是先修课程,它的值是必须在键对应的课程之后学习的所有课程。同时,将每个节点的入度保存到数组inDegrees中,“inDegrees[i]”表示节点i的入度。
接下来用广度优先搜索算法实现拓扑排序。队列中保存的是入度为0的节点。每次从队列中取出一个节点,将该节点添加到拓扑排序序列中,然后找到该课程的后修课程并将它们的节点的入度减1,这相当于删除从先修课程到后修课程的边。如果发现新的入度为0的节点,则将其添加到队列中。重复这个过程直到队列为空,此时要么图中所有节点都已经访问完毕,已经得到了完整的拓扑排序序列;要么剩下的还没有搜索到的节点形成一个环,已经不存在入度为0的节点。

public class Test {
    public static void main(String[] args) {
        int[][] prerequisites = {{1, 0}, {2, 0}, {3, 1}, {3, 2}};
        int[] result = findOrder(4, prerequisites);
        for (int item : result) {
            System.out.println(item);
        }
    }

    public static int[] findOrder(int numCourses, int[][] prerequisites) {
        // graph用一个HashMap表示邻接表,它的键是先修课程,它的值是必须在键对应的课程之后学习的所有课程
        Map<Integer, List<Integer>> graph = new HashMap<>();
        for (int i = 0; i < numCourses; i++) {
            graph.put(i, new LinkedList<>());
        }

        // 表示节点i的入度
        int[] inDegrees = new int[numCourses];
        for (int[] prereq : prerequisites) {
            graph.get(prereq[1]).add(prereq[0]);
            inDegrees[prereq[0]]++;
        }

        Queue<Integer> queue = new LinkedList<>();
        for (int i = 0; i < numCourses; i++) {
            if (inDegrees[i] == 0) {
                queue.add(i);
            }
        }

        List<Integer> order = new LinkedList<>();
        while (!queue.isEmpty()) {
            int course = queue.remove();
            order.add(course);
            for (int next : graph.get(course)) {
                inDegrees[next]--;
                if (inDegrees[next] == 0) {
                    queue.add(next);
                }
            }
        }

        return order.size() == numCourses ? order.stream().mapToInt(i -> i).toArray() : new int[0];
    }

}
文章来源:https://blog.csdn.net/GoGleTech/article/details/135531867
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。