你将会获得一系列视频片段,这些片段来自于一项持续时长为 time 秒的体育赛事。这些片段可能有所重叠,也可能长度不一。
使用数组 clips 描述所有的视频片段,其中 clips[i] = [starti, endi] 表示:某个视频片段开始于 starti 并于 endi 结束。
甚至可以对这些片段*地再剪辑:
例如,片段 [0, 7] 可以剪切成 [0, 1] + [1, 3] + [3, 7] 三部分。
我们需要将这些片段进行再剪辑,并将剪辑后的内容拼接成覆盖整个运动过程的片段([0, time])。返回所需片段的最小数目,如果无法完成该任务,则返回 -1 。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/video-stitching
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
排序 + 优先队列
import java.util.Arrays;
import java.util.Comparator;
import java.util.PriorityQueue;
class Solution {
public int videoStitching(int[][] clips, int time) {
if (clips == null || clips.length == 0) {
return -1;
}
Arrays.sort(clips, new Comparator<int[]>() {
@Override
public int compare(int[] o1, int[] o2) {
return Integer.compare(o1[0], o2[0]);
}
});
int ret = 0;
int curPos = 0;
PriorityQueue<int[]> queue = new PriorityQueue<>(new Comparator<int[]>() {
@Override
public int compare(int[] o1, int[] o2) {
return Integer.compare(o2[1], o1[1]);
}
});
int idx = 0;
while (idx < clips.length) {
while (idx < clips.length && clips[idx][0] <= curPos) {
queue.offer(clips[idx++]);
}
if (queue.isEmpty()) {
return -1;
}
int[] best = queue.poll();
if (best[1] > curPos) {
curPos = best[1];
ret++;
if (curPos >= time) {
return ret;
}
queue.clear();
} else {
return -1;
}
}
return -1;
}
}
动态规划
import java.util.Arrays;
class Solution {
public int videoStitching(int[][] clips, int time) {
if (clips == null || clips.length == 0) {
return -1;
}
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];
}
}
贪心
import java.util.Arrays;
class Solution {
public int videoStitching(int[][] clips, int time) {
if (clips == null || clips.length == 0) {
return -1;
}
int[] maxDistance = new int[time];
for (int[] clip : clips) {
if (clip[0] < time) {
maxDistance[clip[0]] = Math.max(maxDistance[clip[0]], clip[1]);
}
}
int ret = 0, pre = 0, last = 0;
for (int i = 0; i < time; ++i) {
last = Math.max(last, maxDistance[i]);
if (last == i) {
return -1;
}
if (i == pre) {
ret++;
pre = last;
}
}
return ret;
}
}