Leetcode 1024. 视频拼接(中等) 贪心算法

labuladong讲解

1024. 视频拼接(中等)

题目:

 

 思路:

给定一个目标区间和若干小区间,如何通过裁剪和组合小区间拼凑出目标区间?最少需要几个小区间?

这道题的以下两个特点:

1、要用若干短视频凑出完成视频[0, T],至少得有一个短视频的起点是 0。

这个很好理解,如果没有一个短视频是从 0 开始的,那么区间[0, T]肯定是凑不出来的。

2、如果有几个短视频的起点都相同,那么一定应该选择那个最长(终点最大)的视频。

 

基于以上两个特点,将clips按照起点升序排序,起点相同的按照终点降序排序

我们会比较所有起点小于clips[0][1]的区间,根据贪心策略,它们中终点最大的那个区间就是第二个会被选中的视频

然后可以通过第二个视频区间贪心选择出第三个视频,以此类推,直到覆盖区间[0, T],或者无法覆盖返回 -1。

 

class Solution {
public:
    int videoStitching(vector<vector<int>>& clips, int time) {
        // 按起点升序排列,起点相同的降序排列
        sort(clips.begin(),clips.end(),[](vector<int>& a,vector<int>& b){
            if(a[0]==b[0]) return a[1]>b[1];
            return a[0]<b[0];
        });
        int n=clips.size();
        int i=0;
        int curEnd=0,nextEnd=0;
        // 记录选择的短视频个数
        int count=0;
        while(i<n&&clips[i][0]<=curEnd){
            // 在第 res 个视频的区间内贪心选择下一个视频
            // 选取起点在上一个选取视频终点前的区间中end最大的
            while(i<n&&clips[i][0]<=curEnd){
                nextEnd=max(nextEnd,clips[i][1]);
                i++;
            }
            // 找到下一个视频,更新 curEnd
            count++;
            curEnd=nextEnd;
            if(curEnd>=time){
                // 已经可以拼出区间 [0, T]
                return count;
            }
        }
        // 无法连续拼出区间 [0, T]
        return -1;
    }
};

 

posted @ 2022-03-04 19:31  鸭子船长  阅读(109)  评论(0编辑  收藏  举报