LeetCode 1024.视频拼接

LeetCode有心哟,特地在10月24号选择了第1024题.

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
8
> 输入: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
5
> 输入:clips = [[0,1],[1,2]], T = 5
> 输出:-1
> 解释:
> 我们无法只用 [0,1] 和 [1,2] 覆盖 [0,5] 的整个过程。
>

示例 3:

1
2
3
4
5
> 输入: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
5
> 输入: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开始,我们肯定要选取0--n, n当然是越大越好.
  3. 当我们找到第一个n, 我们要继续去访问余下的元素有没有视频起始点小于等于n,且它的长度越长就越好.
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
class Solution {
public:
int videoStitching(vector<vector<int>>& clips, int T) {
if (clips.empty()) return -1;
sort(clips.begin(), clips.end(), [](vector<int>A, vector<int>B){
if (A[0] < B[0]) return true;
else if (A[0] == B[0]) return A[1] < B[1];
return false;
});
int ans = 0;
int cur_max = 0, pre_max = 0;
int size = clips.size(), i = 0;
while (i < size && cur_max < T){
// 只有当cur_max >= clips[i][0] 才有可能合并
if (clips[i][0] <= cur_max){
pre_max = cur_max;
// 挑选出能够着的最大值 pre_max是门槛
while(i < size && pre_max >= clips[i][0]){
cur_max = max(cur_max, clips[i][1]);
i++;
}
ans++;
}
else
break;
}
return cur_max >= T ? ans : -1;
}
};