• 【算法】区间调度算法


    1.概述

    (1)区间调度算法 (Interval Scheduling Algorithm) 是一种在给定的一组任务中,选择尽可能多的相互不冲突的任务的算法。在这个问题中,每个任务都有一个开始时间和结束时间。两个任务是相互冲突的,当且仅当它们的时间段有重叠部分。目标是选择最大数量的任务,使得它们不相互冲突。

    (2)该问题可以用贪心算法解决,其基本思想是按照任务结束时间的顺序,依次选择结束时间最早的任务,并且保证该任务与之前已选任务不冲突。具体实现步骤如下:

    • ① 将任务按照结束时间从早到晚排序;
    • ② 选择结束时间最早的任务,并将其加入最终结果集合中;
    • ③ 对于剩余任务中与已选任务不冲突的任务,重复步骤 ②,直到没有剩余任务为止。

    (3)下面是一个示例:

    • 假设有 5 个任务:(1,3), (2,5), (4,7), (6,9), (8,10),其中每个任务用一对时间表示其起始时间和结束时间。
    • 按照结束时间从早到晚的顺序,它们的排序结果为:(1,3), (2,5), (4,7), (6,9), (8,10)。
    • 根据上述贪心算法,首先选择结束时间最早的任务 (1,3),然后排除掉与该任务冲突的任务 (2,5),接着选择结束时间最早的任务 (4,7),再排除掉与该任务冲突的任务 (6,9),最后选择结束时间最早的任务 (8,10),得到的最终结果集合为 {(1,3), (4,7), (8,10)}。

    区间调度算法的时间复杂度为 O(nlogn),其中 n 是任务数量,主要来自于对任务按照结束时间进行排序。

    2.代码实现

    (1)区间调度算法的代码实现如下:

    class Solution {
        public List<int[]> schedule(int[][] intervals) {
            //将所有区间按照其右端点的值进行升序排序
            Arrays.sort(intervals, Comparator.comparingInt(a -> a[1]));
            //存放选择的区间
            List<int[]> selected = new ArrayList<>();
            selected.add(intervals[0]);
            int end = intervals[0][1];
            for (int[] interval : intervals) {
                if (end < interval[0]) {
                    //找到一个与当前区间不相交的区间
                    selected.add(interval);
                    //更新 end
                    end = interval[1];
                }
            }
            return selected;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    (2)测试代码如下:

    class Test {
        public static void main(String[] args) {
            int[][] intervals = {{1, 4}, {2, 3}, {3, 6}, {5, 7}, {6, 8}, {8, 10}};
            Solution solution = new Solution();
            List<int[]> selected = solution.schedule(intervals);
            for (int[] interval : selected) {
                System.out.println(Arrays.toString(interval));
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    输出结果如下:

    [2, 3]
    [5, 7]
    [8, 10]
    
    • 1
    • 2
    • 3

    3.应用

    (1)区间调度算法的应用场景包括:

    • 会议安排问题:有多个会议需要在同一天内安排,但每个会议的时间可能重叠。现在需要找到一种方案,使得尽可能多的会议都可以被安排,并且每个时间段只能安排一场会议。
    • 老师安排课程表问题:有多位老师需要在同一时间段上课,但每位老师的课程可能存在时间上的重叠。现在需要找到一种方案,使得尽可能多的老师都可以安排课程,并且每个时间段只能安排一位老师的课程。
    • 医生安排手术问题:医院有多名医生需要在同一时间段进行手术,但每名医生手术的时间可能存在重叠。现在需要找到一种方案,使得尽可能多的医生都可以进行手术,并且每个时间段只能安排一名医生的手术。

    以上仅是应用场景的一部分,区间调度算法还可以应用于其他需要优化时间资源利用的问题。

    (2)大家可以去 LeetCode 上找相关的区间调度算法的题目来练习,或者也可以直接查看 LeetCode 算法刷题目录 (Java) 这篇文章中的区间问题章节。如果大家发现文章中的错误之处,可在评论区中指出。

  • 相关阅读:
    【解惑】时间规划,Linq的Aggregate函数在计算会议重叠时间中的应用
    从指针开始变强(四)之超级详细笔试题(二)
    分布式编程工具Akka Streams、Kafka Streams和Spark Streaming大PK
    原语:串并转换器
    Matplotlib:科研绘图利器(写论文、数据可视化必备)
    猿创征文|『编程与创作』10款颜值颇高的宝藏工具
    Python150题day17
    jupyter notebook 调整深色背景与单元格宽度与自动换行
    开源监控软件Zabbix5部署实战
    【调试】ftrace(一)基本使用方法
  • 原文地址:https://blog.csdn.net/weixin_43004044/article/details/134527888