leetcode - 354. Russian Doll Envelopes

文章描述了一个二维数组表示的信封问题,目标是找到能俄罗斯套娃的最大信封数量。解决方案是首先按宽度对信封排序,然后使用贪心策略结合二分查找插入信封,确保始终选择最优的高度。这种方法的时间复杂度为O(nlogn),空间复杂度为O(n)。
摘要由CSDN通过智能技术生成

Description

You are given a 2D array of integers envelopes where envelopes[i] = [wi, hi] represents the width and the height of an envelope.

One envelope can fit into another if and only if both the width and height of one envelope are greater than the other envelope’s width and height.

Return the maximum number of envelopes you can Russian doll (i.e., put one inside the other).

Note: You cannot rotate an envelope.

Example 1:

Input: envelopes = [[5,4],[6,4],[6,7],[2,3]]
Output: 3
Explanation: The maximum number of envelopes you can Russian doll is 3 ([2,3] => [5,4] => [6,7]).

Example 2:

Input: envelopes = [[1,1],[1,1],[1,1]]
Output: 1

Constraints:

1 <= envelopes.length <= 10^5
envelopes[i].length == 2
1 <= wi, hi <= 10^5

Solution

300. LIS的进阶版,用贪心+二分做

按照LIS贪心的思路,同样保存一个栈,每次插入新的信封时,将信封插在能吞掉前一个信封的后面位置,如对于[[3,4], [12,8]]这样的栈,遇到[12,2]时,将[12,2]插入到索引0的位置,遇到[12,5]时,将[12,5]插入到索引1的位置

因为是贪心的思路,所以先对信封按照width排序,这样可以保证每次选出比较小的width。但是对于height,因为插入的逻辑,会始终保持把后面的信封插入到栈里,因此要对height按照降序排列,这样保证后面插入的是更优的

寻找插入的索引位置时,用二分即可。因为我们要找到能吞掉的信封右边的索引,所以当mid对应的信封能被吞掉时,丢弃left - mid这一段即可

时间复杂度: o ( n log ⁡ n ) o(n\log n) o(nlogn)
空间复杂度: o ( n ) o(n) o(n)

Code

贪心+二分

class Solution:
    def maxEnvelopes(self, envelopes: List[List[int]]) -> int:
        def bisect_2d(a: list, x: list) -> int:
            left, right = 0, len(a) - 1
            while left < right:
                mid = (left + right) // 2
                if a[mid][0] < x[0] and a[mid][1] < x[1]:
                    left = mid + 1
                else:
                    right = mid
            return left
        
        envelopes.sort(key=lambda x: (x[0], -x[1]))
        aux_stack = [envelopes[0]]
        for each_envelope in envelopes[1:]:
            if each_envelope[0] > aux_stack[-1][0] and each_envelope[1] > aux_stack[-1][1]:
                aux_stack.append(each_envelope)
            else:
                insert_index = bisect_2d(aux_stack, each_envelope)
                aux_stack[insert_index] = each_envelope
        return len(aux_stack)

dp

o ( n 2 ) o(n^2) o(n2)的dp,没什么好说的,会吃TLE

class Solution:
    def maxEnvelopes(self, envelopes: List[List[int]]) -> int:
        envelopes.sort()
        dp = [1] * len(envelopes)
        for i in range(1, len(envelopes)):
            for j in range(i):
                if envelopes[i][0] > envelopes[j][0] and envelopes[i][1] > envelopes[j][1]:
                    dp[i] = max(dp[j] + 1, dp[i])
        return max(dp)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值