「每日LeetCode」2020年10月24日-1024快乐

本文最后更新于:2023年3月19日 晚上

Lt1024. 视频拼接,贪心算法

1024. 视频拼接

你将会获得一系列视频片段,这些片段来自于一项持续时长为 T 秒的体育赛事。这些片段可能有所重叠,也可能长度不一。
视频片段 clips[i] 都用区间进行表示:开始于 clips[i][0] 并于 clips[i][1] 结束。我们甚至可以对这些片段自由地再剪辑,例如片段 [0, 7] 可以剪切成 [0, 1] + [1, 3] + [3, 7] 三部分。
我们需要将这些片段进行再剪辑,并将剪辑后的内容拼接成覆盖整个运动过程的片段([0, T])。返回所需片段的最小数目,如果无法完成该任务,则返回 -1

示例 1:

1
2
3
4
5
6
7
输入: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:

1
2
3
4
输入:clips = [[0,1],[1,2]], T = 5
输出:-1
解释:
我们无法只用 [0,1][1,2] 覆盖 [0,5] 的整个过程。

示例 3:

1
2
3
4
输入: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:

1
2
3
4
输入:clips = [[0,4],[2,8]], T = 5
输出:2
解释:
注意,你可能录制超过比赛结束时间的视频。

提示:

  • 1 <= clips.length <= 100
  • 0 <= clips[i][0] <= clips[i][1] <= 100
  • 0 <= T <= 100

思路

注意到对于所有左端点相同的子区间,其右端点越远越有利
贪心算法,执行以下过程:

  1. 首先将数组按照区间大小降序排序
  2. 求是否存在以 0 开始的区间,不存在则返回-1
  3. 当 max<T,持续进行区间选取,循环具体逻辑:
    1. 使用一个临时数组等于排序之后的数组。
    2. 使用 filter 取到左端点在上一个已取区间内,右端点在已取区间外的所有区间。
    3. 令这些区间的左端点都为上一个已取区间的右端点,这样所有左端点子区间都相同了。
    4. 按区间大小降序排序,其实就是取右端点最远的那个区间。
    5. 如果存在这样的区间,则取该区间,将最左最右端点设为区间的端点。
    6. 如果不存在则返回-1。
  4. 返回 count 结果

解答

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
/**
* @param {number[][]} clips
* @param {number} T
* @return {number}
*/
var videoStitching = function (clips, T) {
clips.sort((a, b) => Number(b[1] - b[0]) - Number(a[1] - a[0]));
let count = 0;
let [min, max] = [0, -Infinity];
const arr = clips.filter((e) => e[0] === 0);
if (arr.length) {
min = arr[0][0];
max = arr[0][1];
count++;
} else {
return -1;
}
while (max < T) {
const temp = clips
.concat()
.filter((e) => e[1] > max && e[0] <= max)
.map((e) => [max, e[1]])
.sort((a, b) => Number(b[1] - b[0]) - Number(a[1] - a[0]));
if (temp.length) {
min = temp[0][0];
max = temp[0][1];
count++;
} else {
return -1;
}
}
return count;
};