leetcode - 354. Russian Doll Envelopes

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)

你可能感兴趣的:(leetcode,算法,职场和发展)