2025-08-09:重新安排会议得到最多空余时间Ⅱ。用go语言,给出一个整数 eventTime,表示活动从 t=0 到 t=eventTime 的时间区间。还有两个长度为 n 的数组 startTime 和 endTime,表示 n 个互不重叠的会议,第 i 个会议占据时间段 [startTime[i], endTime[i]]。
你可以最多对其中一个会议做平移操作(仅改变其起止时间位置,时长保持不变),并且移动后的会议必须仍然位于 [0, eventTime] 之内且与其它会议互不重叠。移动后各会议的先后顺序可以改变,也可以选择不移动任何会议。
目标是通过至多一次这样的平移,使时间轴上最长的不被任何会议占用的连续时段尽可能长。请输出在最佳移动方案下这一最长连续空闲时长。
1 <= eventTime <= 1000000000。
n == startTime.length == endTime.length。
2 <= n <= 100000。
0 <= startTime[i] < endTime[i] <= eventTime。
endTime[i] <= startTime[i + 1] 其中 i 在范围 [0, n - 2] 之间。
输入:eventTime = 5, startTime = [1,3], endTime = [2,5]。
输出:2。
解释:
将 [1, 2] 的会议安排到 [2, 3] ,得到空余时间 [0, 2] 。
题目来自力扣3440。
startTime[0] - 0
startTime[i] - endTime[i-1]
对所有 i
eventTime - endTime[n-1]
i
可以尝试将其放在某个位置,使得其前后的空闲时间合并。max_gap
。i
,尝试将其移除,然后计算移除后的空闲时间(即 startTime[i+1] - endTime[i-1]
,假设 i
不是首尾会议)。i
插入到其他位置,使得插入后的空闲时间最大化。startTime[i] = 0
,endTime[i] = duration
,检查是否与 startTime[0]
重叠。endTime[i] = eventTime
,startTime[i] = eventTime - duration
,检查是否与 endTime[n-1]
重叠。i
插入到其他会议之间的间隙中,确保不重叠。max_gap
。i
的最优效果通常是将其“填补”到某个小的间隙中,从而合并两个相邻的空闲时间。i
,其持续时间为 duration = endTime[i] - startTime[i]
。i
后,其左右的空闲时间为 left_gap = startTime[i] - endTime[i-1]
和 right_gap = startTime[i+1] - endTime[i]
(假设 i
不是首尾)。i
插入到其他位置后,原来的 left_gap + right_gap + duration
会成为新的空闲时间(因为移除了会议 i
的占用)。max_gap
。i
:i
后的空闲时间 removed_gap = startTime[i+1] - endTime[i-1]
(假设 i
不是首尾)。i
的持续时间 duration = endTime[i] - startTime[i]
。i
插入到其他间隙中:duration <= startTime[0]
,则新的空闲时间为 startTime[0] - duration
。duration <= eventTime - endTime[n-1]
,则新的空闲时间为 eventTime - endTime[n-1] - duration
。j
(即 startTime[j] - endTime[j-1] >= duration
):startTime[j] - endTime[j-1] - duration
。max(removed_gap, new_gap)
的位置。max_gap
。以 eventTime = 5
,startTime = [1, 3]
,endTime = [2, 5]
为例:
1 - 0 = 1
3 - 2 = 1
5 - 5 = 0
max_gap = 1
。[1, 2]
):3 - 0 = 3
。1
。[0, 1]
,剩余空闲 3 - 1 = 2
(因为 [0,1]
和 [3,5]
之间的空闲是 3 - 1 = 2
)。5 - 5 = 0 < 1
)。max_gap = max(3, 2) = 3
(但实际空闲是 [0,1]
和 [1,3]
之间的 0
,[3,5]
之间的 0
,所以可能是 max(1, 2)
)。[0,1]
后,会议为 [0,1]
和 [3,5]
,空闲时间为 3 - 1 = 2
和 5 - 5 = 0
,所以 max_gap = 2
。[3,5]
):5 - 2 = 3
。2
。[0, 2]
,剩余空闲 1 - 0 = 1
(因为 [0,2]
和 [1,2]
重叠,不合法)。5 - 5 = 0 < 2
)。[1,2]
和 [3,5]
之间的间隙是 3 - 2 = 1 < 2
,无法插入。max_gap = 2
(通过移动会议 0 到 [0,1]
或 [2,3]
)。max_gap
:O(n)
。i
,尝试移动:O(1)
。O(n)
。O(n^2)
,但对于 n <= 1e5
来说不可行。i
,尝试插入到最大的可用间隙中,可以优化到 O(n log n)
或 O(n)
。O(n)
。i
,移除后可以尝试插入到最大的间隙中(只要 duration <= gap
)。O(n log n)
(排序间隙)或 O(n)
(如果间隙已经有序)。对于给定的示例,输出 2
。
.
package main
import (
"fmt"
)
func maxFreeTime(eventTime int, startTime []int, endTime []int)int {
n := len(startTime)
q := make([]bool, n)
t1, t2 := 0, 0
for i := 0; i < n; i++ {
if endTime[i]-startTime[i] <= t1 {
q[i] = true
}
if i == 0 {
t1 = max(t1, startTime[i])
} else {
t1 = max(t1, startTime[i]-endTime[i-1])
}
if endTime[n-i-1]-startTime[n-i-1] <= t2 {
q[n-i-1] = true
}
if i == 0 {
t2 = max(t2, eventTime-endTime[n-1])
} else {
t2 = max(t2, startTime[n-i]-endTime[n-i-1])
}
}
res := 0
for i := 0; i < n; i++ {
left := 0
if i != 0 {
left = endTime[i-1]
}
right := eventTime
if i != n-1 {
right = startTime[i+1]
}
if q[i] {
res = max(res, right-left)
} else {
res = max(res, right-left-(endTime[i]-startTime[i]))
}
}
return res
}
func main() {
eventTime := 5
startTime := []int{1, 3}
endTime := []int{2, 5}
result := maxFreeTime(eventTime, startTime, endTime)
fmt.Println(result)
}
.
# -*-coding:utf-8-*-
def max_free_time(eventTime: int, startTime: list, endTime: list) -> int:
n = len(startTime)
if n == 0:
return eventTime
q = [False] * n
t1, t2 = 0, 0
for i in range(n):
if endTime[i] - startTime[i] <= t1:
q[i] = True
if i == 0:
t1 = max(t1, startTime[i])
else:
t1 = max(t1, startTime[i] - endTime[i-1])
j = n - i - 1
if endTime[j] - startTime[j] <= t2:
q[j] = True
if i == 0:
t2 = max(t2, eventTime - endTime[n-1])
else:
# 对应 Go 中的 startTime[n-i] - endTime[n-i-1]
t2 = max(t2, startTime[n - i] - endTime[n - i - 1])
res = 0
for i in range(n):
left = 0if i == 0else endTime[i-1]
right = eventTime if i == n-1else startTime[i+1]
if q[i]:
res = max(res, right - left)
else:
res = max(res, right - left - (endTime[i] - startTime[i]))
return res
if __name__ == "__main__":
eventTime = 5
startTime = [1, 3]
endTime = [2, 5]
result = max_free_time(eventTime, startTime, endTime)
print(result)