leetcode1024(视频拼接:贪心算法)

你将会获得一系列视频片段,这些片段来自于一项持续时长为 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]。

题解:贪心算法,分析题目后可以发现这道题的本质是找出能覆盖长度为T的区间的最小区间集合数。要使区间集合数最小,则对于起点相同的子区间,我们要优先选择长度更长的区间,于是我们需要预处理子区间,用数组 int maxEdge[ i ] 记录对于每一个位置i,其最远子区间的右端点maxEdge[ i ]。
预处理完后,我们就可以采用贪心算法,我们枚举长度为T的区间的每一个位置i,用一个指针edge更新左端点不大于i的所有区间可以取得的最大右端点,每当我们枚举到一个新位置时,我们用maxEdge[ i ]来更新指针edge,如果当枚举到某个位置满足i==edge时,说明不存在区间可以覆盖当前位置,则返回-1。我们还需要一个指针lastEdge指向当前区间的右端点,当i = = == ==lastEdge时,说明要更新区间,则结果区间数量+1。

class Solution {
     
    public int videoStitching(int[][] clips, int T) {
     
          int[]maxEdge=new int[T+1];
          int edge=0;
          int lastEdge=0;
          int ans=0;
          for (int[] clip : clips) {
     
              if(clip[0]<=T) {
     
                  maxEdge[clip[0]] = Math.max(clip[1], maxEdge[clip[0]]);
              }
          }
          for(int i=0;i<T;i++){
     
              edge=Math.max(edge,maxEdge[i]);
              if(edge==i){
     
                  return -1;
              }else if(i==lastEdge){
     
                  lastEdge=edge;
                  ans++;
              }
          }
          return ans;
    }
}

你可能感兴趣的:(每天一道算法题,1024程序员节)