快轉到主要內容
  1. LeetCode/

LeetCode 3439: Reschedule Meetings for Maximum Free Time (Sliding Window)

·2 分鐘· ·
LeetCode Daily Medium Sliding Window Two Pointers Intervals Array
Wei Yi Chung
作者
Wei Yi Chung
Working at the contributing of open source, distributed systems, and data engineering.
目錄

基本資料
#

難易度: Medium 第一次嘗試: 2025-08-09

  • 總花費時間:00:00.00

解題思路
#

會議已排序且不重疊。若把最多 k 個連續會議移到其他時間,留下的空檔介於「區塊左側上一個會議的結束」與「區塊右側下一個會議的開始」之間(或日程邊界)。空檔長度 = 右邊界 − 左邊界 −(區塊內所有會議的總時長)。

為了 O(1) 地移動視窗,維護「區塊內會議總時長」:

  • 先計算前 k 場的總時長作為初始視窗;若 n ≤ k,代表可移走全部會議,答案為 eventTime - sum(endTime) + sum(startTime)
  • 若 k < n,初始答案為 startTime[k] - meeting_time
  • 接著令 i 從 k 迭代到 n-1:每一步把第 i 場加入、把第 i-k 場移出,更新 meeting_time
  • 邊界:left = endTime[i - k]right = startTime[i + 1](若 i 為最後一場,right = eventTime)。
  • right - left - meeting_time 更新最大空檔。

解法
#

  • 使用滑動視窗代表要移動的會議區塊,維護區塊大小與區塊內總時長。
  • 當視窗超過 k,就從左側移出最舊的會議並從總時長扣除。
  • 左邊界:0endTime[idx - k];右邊界:eventTimestartTime[idx + 1]
  • 每一步用 right - left - meeting_times 更新答案。

Directly iterate the meeting times
#

class Solution:
    def maxFreeTime(self, eventTime: int, k: int, startTime: List[int], endTime: List[int]) -> int:

        meeting_times = meeting_counts = max_free = 0
        for idx, (s, e) in enumerate(zip(startTime, endTime)):
            meeting_times += e - s
            meeting_counts += 1
            
            if meeting_counts > k:
                meeting_counts -= 1
                meeting_times -= endTime[idx - k] - startTime[idx - k]

            left = 0 if (idx - k + 1) <= 0 else endTime[idx - k]
            right = eventTime if idx == len(startTime) - 1 else startTime[idx + 1]
            max_free = max(max_free, right - left - meeting_times)

        return max_free

Count the first window and slide the window
#

class Solution:
    def maxFreeTime(self, eventTime: int, k: int, startTime: List[int], endTime: List[int]) -> int:
        n = len(startTime)
        if n <= k:
            return eventTime - sum(endTime) + sum(startTime)

        meeting_time = 0
        for i in range(k):
            meeting_time += endTime[i] - startTime[i]
        
        max_free = startTime[k] - meeting_time

        for i in range(k, n):
            meeting_time += endTime[i] - startTime[i]
            meeting_time -= endTime[i - k] - startTime[i - k]

            right = startTime[i + 1] if i < n - 1 else eventTime
            left = endTime[i - k]

            max_free = max(max_free, right - left - meeting_time)

        return max_free

複雜度
#

  • 時間複雜度:O(n)
  • 空間複雜度:O(1)

收穫
#

  • 維護區塊內總時長讓視窗移動的更新是 O(1)。
  • 空檔由視窗兩側邊界決定,扣掉視窗內的會議總長度即可。

遇到的問題
#

相關文章

LeetCode 1695: Maximum Erasure Value (Sliding Window)
·1 分鐘
LeetCode Daily Medium Sliding Window Two Pointers Array Hashset
LeetCode 解題紀錄
LeetCode 209: Minimum Size Subarray Sum
·1 分鐘
LeetCode Daily Medium Array Sliding Window Two Pointers Prefix Sum Binary-Search
滑動視窗與雙指針,最小化子陣列長度(總和 ≥ target)。
LeetCode 30: Substring with Concatenation of All Words
·2 分鐘
LeetCode Daily Hard String Sliding Window Two Pointers Hash Map Frequency-Counter Brute-Force
三種作法:暴力、計數優化、偏移量滑動視窗。
LeetCode 1004: Max Consecutive Ones III
·1 分鐘
LeetCode Daily Medium Sliding Window Array Two Pointers Binary Array
LeetCode 解題紀錄 - 可變大小滑動窗口與零計數
LeetCode 1052: Grumpy Bookstore Owner
·1 分鐘
LeetCode Daily Medium Sliding Window Array Optimization Fixed Window
LeetCode 解題紀錄 - 固定窗口與客戶滿意度優化
LeetCode 1658: Minimum Operations to Reduce X to Zero
·1 分鐘
LeetCode Daily Medium Sliding Window Array Reverse Thinking Prefix Sum
LeetCode 解題紀錄 - 反向思考與滑動窗口