读完本文,可以去力扣解决如下题目:
1024. 视频拼接(Medium)
前面发过 几个视频,也算是对视频剪辑入了个门。像我这种非专业剪辑玩家,不做什么宏大特效电影镜头,只是做个视频教程,其实也没啥难度,只需要把视频剪流畅,所以用到最多的功能就是切割功能,然后删除和拼接视频片接。
没有剪过视频的读者可能不知道,在常用的剪辑软件中视频被切割成若干片段之后,每个片段都可以还原成原始视频。
就比如一个 10 秒的视频,在中间切一刀剪成两个 5 秒的视频,这两个五秒的视频各自都可以还原成 10 秒的原视频。就好像蚯蚓,把自己切成 4 段就能搓麻,把自己切成 11 段就可以凑一个足球队。
剪视频时,每个视频片段都可以抽象成了一个个区间,时间就是区间的端点,这些区间有的相交,有的不相交……
假设剪辑软件不支持将视频片段还原成原视频,那么如果给我若干视频片段,我怎么将它们还原成原视频呢?
这是个很有意思的区间算法问题,也是力扣第 1024 题「视频拼接」,题目如下:
函数签名如下:
int videoStitching(int[][] clips, int T);
记得以前写过好几篇区间相关的问题:
贪心算法玩跳跃游戏 写的跳跃游戏是相同的,如果你能看出这两者的联系,就可以说理解贪心算法的奥义了。
代码实现
实现上述思路需要我们用两个变量curEnd
和nextEnd
来进行:
最终代码实现如下:
int videoStitching(int[][] clips, int T) {
if (T == 0) return 0;
// 按起点升序排列,起点相同的降序排列
Arrays.sort(clips, (a, b) -> {
if (a[0] == b[0]) {
return b[1] - a[1];
}
return a[0] - b[0];
});
// 记录选择的短视频个数
int res = 0;
int curEnd = 0, nextEnd = 0;
int i = 0, n = clips.length;
while (i < n && clips[i][0] <= curEnd) {
// 在第 res 个视频的区间内贪心选择下一个视频
while (i < n && clips[i][0] <= curEnd) {
nextEnd = Math.max(nextEnd, clips[i][1]);
i++;
}
// 找到下一个视频,更新 curEnd
res++;
curEnd = nextEnd;
if (curEnd >= T) {
// 已经可以拼出区间 [0, T]
return res;
}
}
// 无法连续拼出区间 [0, T]
return -1;
}
这段代码的时间复杂度是多少呢?虽然代码中有一个嵌套的 while 循环,但这个嵌套 while 循环的时间复杂度是O(N)
。因为当i
递增到n
时循环就会结束,所以这段代码只会执行O(N)
次。
但是别忘了我们对clips
数组进行了一次排序,消耗了O(NlogN)
的时间,所以本算法的总时间复杂度是O(NlogN)
。
最后说一句,我去 B 站做 up 了,B 站搜索同名账号「labuladong」即可关注!
查看更多优质算法文章 点击这里,手把手带你刷力扣,致力于把算法讲清楚!我的 算法教程 已经获得 90k star,欢迎点赞!
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。