题目:
你将会获得一系列视频片段,这些片段来自于一项持续时长为 T 秒的体育赛事。这些片段可能有所重叠,也可能长度不一。
视频片段 clips[i] 都用区间进行表示:开始于 clips[i][0] 并于 clips[i][1] 结束。我们甚至可以对这些片段自由地再剪辑,例如片段 [0, 7] 可以剪切成 [0, 1] + [1, 3] + [3, 7] 三部分。
我们需要将这些片段进行再剪辑,并将剪辑后的内容拼接成覆盖整个运动过程的片段([0, T])。返回所需片段的最小数目,如果无法完成该任务,则返回 -1 。
思路1:
注意:本题中区间端点一定是不同的!
动态规划:
dp[i]:覆盖区间[0,i)所需片段的最小数目
初始化:dp[0]=0
状态转移方程:当i>0时,对于每一个片段[start,end],判断i值是否满足start<i<=end,若满足则令dp[i]=min{dp[i],dp[start]+1}。
解答1:
class Solution:
def videoStitching(self, clips: List[List[int]], T: int) -> int:
dp=[0]+[float('inf')]*T
n=len(clips)
for i in range(1,T+1):
for start,end in clips:
if start<i<=end:
dp[i]=min(dp[start]+1,dp[i])
return -1 if dp[T]==float('inf') else dp[T]
思路2:
贪心算法,对于所有左端点相同的子区间,其右端点越远越有利。
利用一个数组maxn,来记录通过已有片段,当前位置所能抵达的最远端
解答2:
class Solution:
def videoStitching(self, clips: List[List[int]], T: int) -> int:
maxn = [0] * T
#last 记录当前能够抵达的最远端
last = res = pre = 0
#对当前片段的start,判断其能够抵达的最远端
for a, b in clips:
if a < T:
maxn[a] = max(maxn[a], b)
#遍历maxn列表,判断当前最远位置。若i==pre,则当前片段结束,片段值加1.
#若i目前已抵达最远端,下一个位置无法抵达,则说明无法完成该任务
for i in range(T):
last = max(last, maxn[i])
if i == last:
return -1
if i == pre:
res += 1
pre = last
return res