列表

详情


1024. 视频拼接

你将会获得一系列视频片段,这些片段来自于一项持续时长为 time 秒的体育赛事。这些片段可能有所重叠,也可能长度不一。

使用数组 clips 描述所有的视频片段,其中 clips[i] = [starti, endi] 表示:某个视频片段开始于 starti 并于 endi 结束。

甚至可以对这些片段自由地再剪辑:

我们需要将这些片段进行再剪辑,并将剪辑后的内容拼接成覆盖整个运动过程的片段([0, time])。返回所需片段的最小数目,如果无法完成该任务,则返回 -1

 

示例 1:

输入:clips = [[0,2],[4,6],[8,10],[1,9],[1,5],[5,9]], time = 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:

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

示例 3:

输入: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]], time = 9
输出:3
解释: 
选取片段 [0,4], [4,7] 和 [6,9] 。

 

提示:

原站题解

去查看

上次编辑到这里,代码来自缓存 点击恢复默认模板
class Solution { public: int videoStitching(vector<vector<int>>& clips, int time) { } };

python3 解法, 执行用时: 44 ms, 内存消耗: 14.9 MB, 提交时间: 2022-12-11 12:30:21

class Solution:
    def videoStitching(self, clips: List[List[int]], time: int) -> int:
        dp = [0] + [float("inf")] * time
        for i in range(1, time + 1):
            for aj, bj in clips:
                if aj < i <= bj:
                    dp[i] = min(dp[i], dp[aj] + 1)
        
        return -1 if dp[time] == float("inf") else dp[time]

golang 解法, 执行用时: 4 ms, 内存消耗: 2 MB, 提交时间: 2022-12-11 12:30:09

func videoStitching(clips [][]int, time int) int {
    const inf = math.MaxInt64 - 1
    dp := make([]int, time+1)
    for i := range dp {
        dp[i] = inf
    }
    dp[0] = 0
    for i := 1; i <= time; i++ {
        for _, c := range clips {
            l, r := c[0], c[1]
            // 若能剪出子区间 [l,i],则可以从 dp[l] 转移到 dp[i]
            if l < i && i <= r && dp[l]+1 < dp[i] {
                dp[i] = dp[l] + 1
            }
        }
    }
    if dp[time] == inf {
        return -1
    }
    return dp[time]
}

java 解法, 执行用时: 2 ms, 内存消耗: 39 MB, 提交时间: 2022-12-11 12:29:57

class Solution {
    public int videoStitching(int[][] clips, int time) {
        int[] dp = new int[time + 1];
        Arrays.fill(dp, Integer.MAX_VALUE - 1);
        dp[0] = 0;
        for (int i = 1; i <= time; i++) {
            for (int[] clip : clips) {
                if (clip[0] < i && i <= clip[1]) {
                    dp[i] = Math.min(dp[i], dp[clip[0]] + 1);
                }
            }
        }
        return dp[time] == Integer.MAX_VALUE - 1 ? -1 : dp[time];
    }
}

cpp 解法, 执行用时: 4 ms, 内存消耗: 7.5 MB, 提交时间: 2022-12-11 12:29:45

// 动态规划,dp[i] 表示将区间 [0,i) 覆盖所需的最少子区间的数量
class Solution {
public:
    int videoStitching(vector<vector<int>>& clips, int time) {
        vector<int> dp(time + 1, INT_MAX - 1);
        dp[0] = 0;
        for (int i = 1; i <= time; i++) {
            for (auto& it : clips) {
                if (it[0] < i && i <= it[1]) {
                    dp[i] = min(dp[i], dp[it[0]] + 1);
                }
            }
        }
        return dp[time] == INT_MAX - 1 ? -1 : dp[time];
    }
};

python3 解法, 执行用时: 36 ms, 内存消耗: 14.9 MB, 提交时间: 2022-12-11 12:28:15

class Solution:
    def videoStitching(self, clips: List[List[int]], time: int) -> int:
        maxn = [0] * time
        last = ret = pre = 0
        for a, b in clips:
            if a < time:
                maxn[a] = max(maxn[a], b)
        
        for i in range(time):
            last = max(last, maxn[i])
            if i == last:
                return -1
            if i == pre:
                ret += 1
                pre = last
        
        return ret

golang 解法, 执行用时: 0 ms, 内存消耗: 2 MB, 提交时间: 2022-12-11 12:28:02

func videoStitching(clips [][]int, time int) (ans int) {
    maxn := make([]int, time)
    last, pre := 0, 0
    for _, c := range clips {
        l, r := c[0], c[1]
        if l < time && r > maxn[l] {
            maxn[l] = r
        }
    }
    for i, v := range maxn {
        if v > last {
            last = v
        }
        if i == last {
            return -1
        }
        if i == pre {
            ans++
            pre = last
        }
    }
    return
}

java 解法, 执行用时: 0 ms, 内存消耗: 39.4 MB, 提交时间: 2022-12-11 12:27:50

class Solution {
    public int videoStitching(int[][] clips, int time) {
        int[] maxn = new int[time];
        int last = 0, ret = 0, pre = 0;
        for (int[] clip : clips) {
            if (clip[0] < time) {
                maxn[clip[0]] = Math.max(maxn[clip[0]], clip[1]);
            }
        }
        for (int i = 0; i < time; i++) {
            last = Math.max(last, maxn[i]);
            if (i == last) {
                return -1;
            }
            if (i == pre) {
                ret++;
                pre = last;
            }
        }
        return ret;
    }
}

cpp 解法, 执行用时: 0 ms, 内存消耗: 7.5 MB, 提交时间: 2022-12-11 12:27:36

// 贪心算法
// 对于所有左端点相同的子区间,其右端点越远越有利。且最佳方案中不可能出现两个左端点相同的子区间。
// 于是我们预处理所有的子区间,对于每一个位置 i,我们记录以其为左端点的子区间中最远的右端点,记为maxn[i]。
class Solution {
public:
    int videoStitching(vector<vector<int>>& clips, int time) {
        vector<int> maxn(time);
        int last = 0, ret = 0, pre = 0;
        for (vector<int>& it : clips) {
            if (it[0] < time) {
                maxn[it[0]] = max(maxn[it[0]], it[1]);
            }
        }
        for (int i = 0; i < time; i++) {
            last = max(last, maxn[i]);
            if (i == last) {
                return -1;
            }
            if (i == pre) {
                ret++;
                pre = last;
            }
        }
        return ret;
    }
};

上一题