python leetcode 俄罗斯套娃信封问题 动态规划算法

题目链接

https://leetcode-cn.com/problems/russian-doll-envelopes/

题目介绍


俄罗斯套娃信封问题

给定一些标记了宽度和高度的信封,宽度和高度以整数对形式 (w, h) 出现。当另一个信封的宽度和高度都比这个信封大的时候,这个信封就可以放进另一个信封里,如同俄罗斯套娃一样。

请计算最多能有多少个信封能组成一组“俄罗斯套娃”信封(即可以把一个信封放到另一个信封里面)。

说明: 不允许旋转信封。

示例:

输入: envelopes = [[5,4],[6,4],[6,7],[2,3]]

输出: 3

解释: 最多信封的个数为 3, 组合为: [2,3] => [5,4] => [6,7]。


class Solution:
    def maxEnvelopes(self, nums: List[List[int]]) -> int:
        # exception
        if not nums:
            return 0
        n = len(nums)
        # 排序
        nums = sorted(nums, key=lambda x: (x[0], -x[1]))
        # 最长递增子序列框架
        dp = [1] * n
        for i in range(n):
            for j in range(i):
                if nums[i][1] > nums[j][1]:
                    dp[i] = max(dp[i], dp[j] + 1)
        return max(dp)

思路

首先读题发现,这个无非是将最长递增子序列扩展到二维而已,比较的元素从一个变成一个列表罢了

任何时候,我都鼓励读者从最简单的实例入手,比如 [[1,1],[2,2],[3,3]],这个很简单无非是遍历两个值比大小嘛

n = len(nums)
for i in range(n):
    for j in range(i):
        if nums[i][0] > nums[j][0] and nums[i][1] > nums[j][1]:
...

接下来,不断上升。试试[[2,2],[1,1],[3,3]],之前的算法是不是是失效了,要思考原因,这里的原因是没有排序,导致[2,2]对应的dp值为1 ,那么我们就先排序再复制上面的不就行了

nums.sort()
#复制上面的即可
...

需要注意的是,sort() 不仅排一维列表,二维也可以,并且全都升序,但是上升到三维就失效了

有人说,这就结束了,不存在的,这可是道hard.如果你直接把这个代码提交,你会得到一个非常变态的测试数据,没错,超时!!原因是我们的if 判断存在冗余,那么,如何优化呢?

我们一开始是两个元素都比,有没有方法只比一个呢?

nums = sorted(nums,key = lambda x: (x[0],-x[1]))
#按照第一个元素升序,第二个元素降序排列
if nums[i][1] > nums[j][1]:

除了if语句改了,其他的不变

那么,为什么要这么排呢?

举个例子,[[2,3],[5,4],[6,7],[6,4]](这是排好的),分为两种情况

1. 第一个元素不相等

因为第一个都按照升序排列,并且不等,所以后面那个大于前面的,就一定满足

2. 第一个元素相等

因为第二个按照降序排列,假设两个相等的为a,b.那么,对a来讲,a因为在前面,所以不会和b比较;对b来讲,虽然与a比较,但因为是降序,b的第二个一定比a来的小,综上,相等的没影响。

当然,这道题的最优解是二分搜索,并非动态规划,这里只是为了开阔读者视野

拓展


读者可能会觉得这里的排序略显骚气,其实python类似的语法不少,简洁好用。

sorted(a,b)

sorted排序时有两个参数,一个是要排序的对象,另一个是依照什么排序,这个时候匿名函数就可以大显身手 类似的还有filter

print(list(filter(lambda x : x % 2 == 0,range(1,10))))

这个会将1-9的偶数输出为一个列表,不同的是,两者对象和参照物的顺序不一样

方法论

做题的时候不是做题,要建立在已经做过的题的基础上,学会先搭框架,后完善。

思考的时候要满足rules of recursition,并且,思维再怎么清晰,考虑的再怎么仔细都不为过

上一篇:Redis 有序集合(sorted set)


下一篇:Redis的sorted_set的用法,看完这一篇就够了