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
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)
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)
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)