一、Problem
你將會獲得一系列視頻片段,這些片段來自於一項持續時長爲 T 秒的體育賽事。這些片段可能有所重疊,也可能長度不一。
視頻片段 clips[i] 都用區間進行表示:開始於 clips[i][0] 並於 clips[i][1] 結束。我們甚至可以對這些片段自由地再剪輯,例如片段 [0, 7] 可以剪切成 [0, 1] + [1, 3] + [3, 7] 三部分。
我們需要將這些片段進行再剪輯,並將剪輯後的內容拼接成覆蓋整個運動過程的片段([0, T])。返回所需片段的最小數目,如果無法完成該任務,則返回 -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]。
提示:
1 <= clips.length <= 100
0 <= clips[i][0] <= clips[i][1] <= 100
0 <= T <= 100
二、Solution
方法一:dp
- 定義狀態:
- 表示將前 個時間點覆蓋完需要的片段數
- 思考初始化:
- 思考狀態轉移方程:
- 如果第 個片段覆蓋到視頻點 ,則有
- 思考輸出:
這裏之是遞推,是長度爲 視頻片段的形成要依賴已拼接好的長度爲 的視頻片段
class Solution {
public int videoStitching(int[][] cs, int T) {
int n = cs.length, INF = 0x3f3f3f3f, f[] = new int[T+1];
Arrays.fill(f, INF); f[0] = 0;
for (int i = 0; i <= T; i++)
for (int j = 0; j < n; j++) {
if (cs[j][0] <= i && cs[j][1] >= i)
f[i] = Math.min(f[i], f[cs[j][0]] + 1);
}
return f[T] == INF ? -1 : f[T];
}
}
複雜度分析
- 時間複雜度:,
- 空間複雜度:,
方法二:貪心
思路
對於某一個視頻片段 cs[i],我們最好的決策就是找一個能與 cs[i] 有交集,且結束時間儘量靠後的一個 cs[idx],然後再以該片段的結束時間 cs[idx][1] 爲起點再做類似的查找
查找過程中,我們可能遇到的最優的還是上一次找到的片段,因此當再用 時間也找不到一個更優的片段時,應立即返回 -1
class Solution {
public int videoStitching(int[][] cs, int T) {
int n = cs.length, e = 0, cnt = 0;
while (e < T) {
int maxE = e;
for (int i = 0; i < n; i++) {
if (cs[i][0] <= e && cs[i][1] > maxE)
maxE = cs[i][1];
}
if (maxE == e)
return -1;
e = maxE;
cnt++;
}
return cnt;
}
}
複雜度分析
- 時間複雜度:,k 爲未知數
- 空間複雜度:,