目录

题目描述

252. 会议室

题意分析

给定一组会议的时间区间 intervals[i] = [start_i, end_i],判断一个人能否参加全部会议。只要存在两个会议在时间上重叠,他就分身乏术,返回 false;否则返回 true。

约束里的关键信号是「区间是左闭右开语义」:一个会议在 end 时刻已经结束,另一个会议正好在同一时刻开始,是可以连着参加的。所以判断重叠的条件是「前一个的结束时间严格大于后一个的开始时间」,[1, 5][5, 8] 不算冲突,[1, 5][4, 8] 才算。

另一个信号是输出只有真假两种,不需要统计冲突了几次、也不需要还原是哪两个会议冲突。这意味着一旦发现第一处冲突就能立刻收工,不必扫完全部数据。

边界包括:数组为空或只有一个会议,此时不存在「两个会议」,应返回 true;两个会议端点相接;输入完全无序,甚至可能出现开始时间相同的会议。

解法:按开始时间排序后检查相邻区间

核心思路

将会议按开始时间升序排列后,时间轴顺序就确定了。若当前会议的开始时间早于前一个会议的结束时间,两场会议重叠,无法全部参加;否则继续检查。

不排序时只能拿每两场会议逐对比较,最坏需要 $O(n^2)$。排序的价值是把时间上最接近的会议放到一起,让全局冲突能够在一次线性扫描中暴露出来。

为什么只看相邻会议:排序后,一旦某个更早的会议延伸到当前会议,它在经过中间会议时就已经产生过相邻重叠并被发现。因此所有相邻区间均不重叠,就能推出任意两场会议都不重叠。

区间按半开语义理解:前一场在 t 结束、后一场在 t 开始可以无缝衔接,所以冲突条件是 currentStart < previousEnd,不是 <=

扫描不变量是:检查第 i 场之前,前 i 场会议已经确认互不重叠。当前场只要不与紧邻的前一场冲突,就能安全加入这段时间线;否则立即返回,无需继续比较。

解题步骤

  • 按每个区间的开始时间升序排序。
  • 从第二个会议开始扫描。
  • intervals[i][0] < intervals[i - 1][1],立即返回 false
  • 扫描结束仍未发现重叠,返回 true

例如 [[0,30],[5,10],[15,20]] 排序后,第二场开始时间 5 小于前一场结束时间 30,直接判定冲突;[[7,10],[10,12]] 则允许首尾相接。

代码实现

import java.util.Arrays;

class Solution {
    public boolean canAttendMeetings(int[][] intervals) {
        Arrays.sort(intervals, (a, b) -> Integer.compare(a[0], b[0]));
        for (int i = 1; i < intervals.length; i++) {
            if (intervals[i][0] < intervals[i - 1][1]) {
                return false;
            }
        }
        return true;
    }
}
import "sort"

func canAttendMeetings(intervals [][]int) bool {
    sort.Slice(intervals, func(i, j int) bool {
        return intervals[i][0] < intervals[j][0]
    })
    for i := 1; i < len(intervals); i++ {
        if intervals[i][0] < intervals[i-1][1] {
            return false
        }
    }
    return true
}

复杂度分析

  • 时间复杂度:$O(n \log n)$,排序占主导,扫描为 $O(n)$。
  • 空间复杂度:取决于排序实现;Java 对对象数组排序最坏使用 $O(n)$ 辅助空间,Go 排序栈为 $O(\log n)$。算法本身只使用常数个变量。

关键点总结

  • 排序把任意区间的冲突问题转成相邻区间检查。
  • 结束时间等于下一场开始时间不算重叠。
  • 发现第一处冲突即可提前返回。
  • 当前实现会改变 intervals 的顺序,这是原地排序的正常结果。

易错点总结

  • 冲突条件写成 <=,会把 [1,2][2,3] 误判为重叠。
  • 按结束时间排序后仍机械地比较相邻区间,论证会改变;本解法必须按开始时间排序。
  • 只比较排序前的相邻会议,会漏掉原数组中不相邻但时间重叠的区间。
  • 比较器写成 a[0] - b[0] 可能整数溢出,应使用 Integer.compare

相似题目

题目 难度 考察点
253. 会议室 II 中等 求最少会议室数量
56. 合并区间 中等 排序后合并重叠区间
57. 插入区间 中等 有序区间中插入并合并
435. 无重叠区间 中等 按结束时间贪心删最少区间
986. 区间列表的交集 中等 双指针求两组区间交集
1229. 安排会议日程 中等 双指针找满足时长的空档
759. 员工空闲时间 困难 多人日程求公共空闲区间