LeetCode 题解工作台

重新安排会议得到最多空余时间 I

给你一个整数 eventTime 表示一个活动的总时长,这个活动开始于 t = 0 ,结束于 t = eventTime 。 同时给你两个长度为 n 的整数数组 startTime 和 endTime 。它们表示这次活动中 n 个时间 没有重叠 的会议,其中第 i 个会议的时间为 [startTim…

category

3

题型

code_blocks

6

代码语言

hub

3

相关题

当前训练重点

中等 · 滑动窗口(状态滚动更新)

bolt

答案摘要

题目相当于把相邻的空闲时间段合并成一个更长的空闲时间段。一共有 $n + 1$ 个空闲时间段,分别是: - 第一个空闲时间段是从活动开始到第一个会议开始的时间段;

Interview AiBox logo

Interview AiBox 实时 AI 助手,陪你讲清 滑动窗口(状态滚动更新) 题型思路

试试 AiBox 面试助手arrow_forward
description

题目描述

给你一个整数 eventTime 表示一个活动的总时长,这个活动开始于 t = 0 ,结束于 t = eventTime 。

同时给你两个长度为 n 的整数数组 startTime 和 endTime 。它们表示这次活动中 n 个时间 没有重叠 的会议,其中第 i 个会议的时间为 [startTime[i], endTime[i]] 。

你可以重新安排 至多 k 个会议,安排的规则是将会议时间平移,且保持原来的 会议时长 ,你的目的是移动会议后 最大化 相邻两个会议之间的 最长 连续空余时间。

移动前后所有会议之间的 相对 顺序需要保持不变,而且会议时间也需要保持互不重叠。

请你返回重新安排会议以后,可以得到的 最大 空余时间。

注意,会议 不能 安排到整个活动的时间以外。

 

示例 1:

输入:eventTime = 5, k = 1, startTime = [1,3], endTime = [2,5]

输出:2

解释:

将 [1, 2] 的会议安排到 [2, 3] ,得到空余时间 [0, 2] 。

示例 2:

输入:eventTime = 10, k = 1, startTime = [0,2,9], endTime = [1,4,10]

输出:6

解释:

将 [2, 4] 的会议安排到 [1, 3] ,得到空余时间 [3, 9] 。

示例 3:

输入:eventTime = 5, k = 2, startTime = [0,1,2,3,4], endTime = [1,2,3,4,5]

输出:0

解释:

活动中的所有时间都被会议安排满了。

 

提示:

  • 1 <= eventTime <= 109
  • n == startTime.length == endTime.length
  • 2 <= n <= 105
  • 1 <= k <= n
  • 0 <= startTime[i] < endTime[i] <= eventTime
  • endTime[i] <= startTime[i + 1] 其中 i 在范围 [0, n - 2] 之间。
lightbulb

解题思路

方法一:滑动窗口

题目相当于把相邻的空闲时间段合并成一个更长的空闲时间段。一共有 n+1n + 1 个空闲时间段,分别是:

  • 第一个空闲时间段是从活动开始到第一个会议开始的时间段;
  • 中间的 n1n - 1 个空闲时间段是相邻两个会议之间的时间段;
  • 最后一个空闲时间段是最后一个会议结束到活动结束的时间段。

题目最多可以重新安排 kk 个会议,等价于最多可以合并 k+1k + 1 个空闲时间段。我们需要找到这 k+1k + 1 个空闲时间段的最大长度。

我们可以将这些空闲时间段的长度存储在一个数组中 nums\textit{nums} 中。然后,我们一个长度为 k+1k + 1 的滑动窗口,遍历这个数组,计算每个窗口的和,找到最大的和,即为所求的最大空闲时间。

时间复杂度 O(n)O(n),空间复杂度 O(n)O(n)。其中 nn 是会议的数量。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Solution:
    def maxFreeTime(
        self, eventTime: int, k: int, startTime: List[int], endTime: List[int]
    ) -> int:
        nums = [startTime[0]]
        for i in range(1, len(endTime)):
            nums.append(startTime[i] - endTime[i - 1])
        nums.append(eventTime - endTime[-1])
        ans = s = 0
        for i, x in enumerate(nums):
            s += x
            if i >= k:
                ans = max(ans, s)
                s -= nums[i - k]
        return ans
speed

复杂度分析

指标
时间complexity is O(n) because each meeting is processed once in the sliding window. Space complexity is O(1) since only running sums and indices are stored, independent of n.
空间O(1)
psychology

面试官常问的追问

外企场景
  • question_mark

    Check if the candidate considers moving meetings versus just counting gaps.

  • question_mark

    Listen for awareness of linear-time updates rather than recomputing each scenario.

  • question_mark

    Notice if they handle edge gaps at the start and end of the event.

warning

常见陷阱

外企场景
  • error

    Forgetting to consider free time before the first or after the last meeting.

  • error

    Recomputing sums naively for each rescheduling window, causing TLE.

  • error

    Miscounting k moves or moving meetings without preserving their durations.

swap_horiz

进阶变体

外企场景
  • arrow_right_alt

    Allow meetings to be split or shortened to create more free time.

  • arrow_right_alt

    Maximize total free time sum instead of the single longest free period.

  • arrow_right_alt

    Limit rescheduling to consecutive meetings only.

help

常见问题

外企场景

重新安排会议得到最多空余时间 I题解:滑动窗口(状态滚动更新) | LeetCode #3439 中等