目录
- 1.概述
- 2.代码实现
- 3.应用
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);//更新 endend = interval[1];}}return selected;}
}
(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));}}
}
输出结果如下:
[2, 3]
[5, 7]
[8, 10]
3.应用
(1)区间调度算法的应用场景包括:
- 会议安排问题:有多个会议需要在同一天内安排,但每个会议的时间可能重叠。现在需要找到一种方案,使得尽可能多的会议都可以被安排,并且每个时间段只能安排一场会议。
- 老师安排课程表问题:有多位老师需要在同一时间段上课,但每位老师的课程可能存在时间上的重叠。现在需要找到一种方案,使得尽可能多的老师都可以安排课程,并且每个时间段只能安排一位老师的课程。
- 医生安排手术问题:医院有多名医生需要在同一时间段进行手术,但每名医生手术的时间可能存在重叠。现在需要找到一种方案,使得尽可能多的医生都可以进行手术,并且每个时间段只能安排一名医生的手术。
以上仅是应用场景的一部分,区间调度算法还可以应用于其他需要优化时间资源利用的问题。
(2)大家可以去 LeetCode 上找相关的区间调度算法的题目来练习,或者也可以直接查看 LeetCode 算法刷题目录 (Java) 这篇文章中的区间问题章节。如果大家发现文章中的错误之处,可在评论区中指出。