【leetcode】一维动态规划题目汇总【视频拼接】

1024. 视频拼接

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

动态规划的方法求解 O(N*L^2)

class Solution:
    def videoStitching(self, clips: List[List[int]], T: int) -> int:
        dp=[0]*(T+1)
        clips=sorted(clips,key=lambda x:x[0])
        for i in range(len(clips)):
            if clips[i][0]==0: 
                dp[min(T,clips[i][1])]=1
            else:   
                break
        for i in range(len(clips)):
            l,r=clips[i][0],min(clips[i][1],T)
            for j in range(l,r+1):
                if not dp[j]==0:
                    for k in range(j,r+1):
                        dp[k]= dp[j]+1 if dp[k]==0 else min(dp[j]+1,dp[k])
        print(dp)
        return dp[T] if not dp[T]==0 else -1

贪心算法求解 O(nlogn + n) = O(nlogn).

这道题和算法书上的活动选择问题基本一致。

利用贪心算法:在开始时间不大于t的视频中选择一个结束时间最大的那一个视频,其中t是上一个选择视频的结束时间。

算法:

  1. 对视频进行升序排列
  2. 选择一个从零开始的视频,它的结束时间是所有从零开始的视频中最大的,赋值给t
  3. 然后在其他视频中选择一个开始时间不超过t的视频,这个被选择的视频的结束时间也应该是最大的,赋值给t
  4. 重复3,直到所有的视频都被遍历,或者t已经大于等于T
class Solution(object):
    def videoStitching(self, clips, T):
        """
        :type clips: List[List[int]]
        :type T: int
        :rtype: int
        """
        clips=sorted(clips,key=lambda x:x[0])
        ans = 0
        last = 0
        for i in range(len(clips)):
            if (last >= T):break
            maxL = last
            j=i
            while (j < len(clips) and clips[j][0] <= last):
                #贪心地在后面区间能够overlap的区间中找最长的
                maxL = max(maxL, clips[j][1])
                j+=1
            if (j == i):return -1;  #//没有能选的就不能覆盖掉区间
            last = maxL
            i = j - 1
            ans+=1
        return -1 if last < T else ans

1277. 统计全为 1 的正方形子矩阵

给你一个 m * n 的矩阵,矩阵中的元素不是 0 就是 1,请你统计并返回其中完全由 1 组成的 正方形 子矩阵的个数。

示例 1:

输入:matrix =
[
[0,1,1,1],
[1,1,1,1],
[0,1,1,1]
]
输出:15
解释:
边长为 1 的正方形有 10 个。
边长为 2 的正方形有 4 个。
边长为 3 的正方形有 1 个。
正方形的总数 = 10 + 4 + 1 = 15.

class Solution(object):
    def countSquares(self, matrix):
        """
        :type matrix: List[List[int]]
        :rtype: int
        """
        from compiler.ast import flatten
        a=[0]*max(len(matrix),len(matrix[0]))
        a[0]=sum(flatten(matrix))
        for i in range(len(matrix)):
            for j in range(len(matrix[0])):
                if matrix[i][j]==1:
                    flag=True
                    area=1
                    while i-area>=0 and j-area>=0 and flag:
                        if self.masum(matrix,i,j,area)==pow(area+1,2):
                            a[area]+=1
                            area=area+1
                        else:
                            flag=False
        return sum(a)
    def masum(self,m,i,j,a):
        t=0
        for ii in range(i-a,i+1):
            for jj in range(j-a,j+1):
                t=t+m[ii][jj]
        return t


猜你喜欢

转载自blog.csdn.net/weixin_42462804/article/details/105936964