难度困难154
给定一些标记了宽度和高度的信封,宽度和高度以整数对形式 (w, h)
出现。当另一个信封的宽度和高度都比这个信封大的时候,这个信封就可以放进另一个信封里,如同俄罗斯套娃一样。
请计算最多能有多少个信封能组成一组“俄罗斯套娃”信封(即可以把一个信封放到另一个信封里面)。
说明:
不允许旋转信封。
示例:
输入: envelopes =[[5,4],[6,4],[6,7],[2,3]]
输出: 3 解释: 最多信封的个数为3, 组合为:
[2,3] => [5,4] => [6,7]。
O(n²)的解法(超时了)
from typing import List
def maxEnvelopes(envelopes: List[List[int]]) -> int:
if not envelopes:#等价于len(envelopes) == 0
return 0
List_Sorted = sorted(envelopes,key = lambda x : (x[0],-x[1]))
num = len(envelopes)
dp = [1] * num
Res = 1#答案最少也是1,因为任何一个子序列的长度都是1
for i in range(num):
for j in range(i):
if List_Sorted[j][1] < List_Sorted[i][1] and dp[j] + 1 > dp[i]:
dp[i] = dp[j] + 1
Res = max(Res,dp[i])
return Res
O(nlogn)的解法:
from typing import List
import bisect
# 这种方法有点像单调栈,列表中是升序的数
def maxEnvelopes(envelopes: List[List[int]]) -> int:
if not envelopes:#等价于len(envelopes) == 0
return 0
List_Sorted = sorted(envelopes,key = lambda x : (x[0],-x[1]))
li = []
for a, b in List_Sorted:
index = bisect.bisect_left(li,b)
if index == len(li):#当前列表li没有元素或者所有元素都严格小于b
li.append(b) #直接将b压入列表li中
else:
li[index] = b
return len(li)