3169.无需开会的工作日

目标

给你一个正整数 days,表示员工可工作的总天数(从第 1 天开始)。另给你一个二维数组 meetings,长度为 n,其中 meetings[i] = [start_i, end_i] 表示第 i 次会议的开始和结束天数(包含首尾)。

返回员工可工作且没有安排会议的天数。

注意:会议时间可能会有重叠。

示例 1:

输入:days = 10, meetings = [[5,7],[1,3],[9,10]]
输出:2
解释:
第 4 天和第 8 天没有安排会议。

示例 2:

输入:days = 5, meetings = [[2,4],[1,3]]
输出:1
解释:
第 5 天没有安排会议。

示例 3:

输入:days = 6, meetings = [[1,6]]
输出:0
解释:
所有工作日都安排了会议。

说明:

  • 1 <= days <= 10^9
  • 1 <= meetings.length <= 10^5
  • meetings[i].length == 2
  • 1 <= meetings[i][0] <= meetings[i][1] <= days

思路

在区间 [1, days] 上有一些区间 [si, ei],求没有被这些区间覆盖的正整数个数。

将区间按起点排序,记录已访问区间的最大终点 prevEndsi - prevEnd - 1 即为当前区间与上一个区间之间的整数个数。注意特殊处理开头与结尾。

网友题解则是合并相交的区间,用总数减去区间覆盖的整数即为答案。

代码


/**
 * @date 2025-07-11 18:53
 */
public class CountDays3169 {

    public int countDays(int days, int[][] meetings) {
        Arrays.sort(meetings, (a, b) -> a[0] - b[0]);
        int res = 0;
        int prevEnd = 0;
        for (int[] meeting : meetings) {
            int interval = meeting[0] - prevEnd - 1;
            res += Math.max(interval, 0);
            prevEnd = Math.max(prevEnd, meeting[1]);
        }
        return res + Math.max(0, days - prevEnd);
    }

}

性能