你将会获得一系列视频片段,这些片段来自于一项持续时长为 T 秒的体育赛事。这些片段可能有所重叠,也可能长度不一。
视频片段 clips[i] 都用区间进行表示:开始于 clips[i][0] 并于 clips[i][1] 结束。我们甚至可以对这些片段自由地再剪辑,例如片段 [0, 7] 可以剪切成 [0, 1] + [1, 3] + [3, 7] 三部分。
我们需要将这些片段进行再剪辑,并将剪辑后的内容拼接成覆盖整个运动过程的片段([0, T])。返回所需片段的最小数目,如果无法完成该任务,则返回 -1 。
示例 1:
输入:clips = [[0,2],[4,6],[8,10],[1,9],[1,5],[5,9]], T = 10 输出:3 解释: 我们选中 [0,2], [8,10], [1,9] 这三个片段。 然后,按下面的方案重制比赛片段: 将 [1,9] 再剪辑为 [1,2] + [2,8] + [8,9] 。 现在我们手上有 [0,2] + [2,8] + [8,10],而这些涵盖了整场比赛 [0, 10]。
示例 2:
输入:clips = [[0,1],[1,2]], T = 5 输出:-1 解释: 我们无法只用 [0,1] 和 [0,2] 覆盖 [0,5] 的整个过程。
示例 3:
输入:clips = [[0,1],[6,8],[0,2],[5,6],[0,4],[0,3],[6,7],[1,3],[4,7],[1,4],[2,5],[2,6],[3,4],[4,5],[5,7],[6,9]], T = 9 输出:3 解释: 我们选取片段 [0,4], [4,7] 和 [6,9] 。
示例 4:
输入:clips = [[0,4],[2,8]], T = 5 输出:2 解释: 注意,你可能录制超过比赛结束时间的视频。
提示:
1 <= clips.length <= 1000 <= clips[i][0], clips[i][1] <= 1000 <= T <= 100
题目标签:Dynamic Programming
题目链接:LeetCode / LeetCode中国
| Language | Runtime | Memory |
|---|---|---|
| python3 | 36 ms | 13.2 MB |
class Solution:
def videoStitching(self, clips: List[List[int]], T: int) -> int:
# 边界情况
if (len(clips) == 0):
return T == 0
elif (len(clips) == 1):
return clips[0][0] == 0 and clips[0][1] == T
clips.sort(key=lambda c : c[0])
# 设范围被包含的片段为无效片段,仅考虑有效片段
valid = [True] * len(clips)
for i in range(len(clips) - 1):
if valid[i]:
for j in range(i + 1, len(clips)):
# j 为无效片段
if clips[i][0] <= clips[j][0] and clips[i][1] >= clips[j][1]:
valid[j] = False
# i 为无效片段
elif clips[j][0] <= clips[i][0] and clips[j][1] >= clips[i][1]:
valid[i] = False;
break
# 必然不会包含,跳过后续比较
elif clips[i][1] >= clips[j][0]:
break
valid_clips = [clips[i] for i in range(len(clips)) if valid[i]]
# 若某个时间点只有一个有效片段,则该片段必选
# 若存在多个可选的片段,选择最迟结束的片段
t = 0 # 检查时间点
pre = -1 # 前一片段索引
res = 0
while t < T:
avail = []
for i in range(pre + 1, len(valid_clips)):
if valid_clips[i][0] <= t <= valid_clips[i][1]:
avail.append(i)
else:
break
if not avail:
return -1
avail.sort(key=lambda x : -1 * valid_clips[x][1])
res += 1
pre = avail[0]
t = valid_clips[pre][1]
return res