【leetcode】354. Russian Doll Envelopes
题目如下:
解题思路:本题有两个维度(宽和高),必须两个维度同时满足条件才行。我们可以把输入数组按其中一个维度排序,例如按宽从小到大排序,如果宽相等,再比较高。这样的话,对于数组中任意一个元素(信封),能够放入该信封的其他信封一定在该信封所在位置的左边。接下来从头开始遍历数组,因为宽度是递增的,因此我们只需要考虑信封的高度,同时我们可以用字典dic[i] = minHeight保存可以放入i个信封的最小高度。对于任意一个信封,只要按key从大到小的顺序比较dic,找到key最大并且其信封高度大于dic[i]即表示这个信封能放入(i)个信封,并且同时更新dic[i+1] = min(dic[i+1],当前信封高度)。这里有一个要注意的是,信封宽度存在相等的情况,而宽度相同的信封是无法互相放入的。因此在更新dic[i+1] = min(dic[i+1],当前信封高度)的时候,需要要先一个holdlist保存要更新的所有数组,只有在当前信封的宽度和下一个信封宽度不相同的时候,才做批量更新。
代码如下:
class Solution(object): def maxEnvelopes(self, envelopes): """ :type envelopes: List[List[int]] :rtype: int """ if len(envelopes) == 0: return 0 def cmpf_w(v1, v2): if v1[0] != v2[0]: return v1[0] - v2[0] return v1[1] - v2[1] envelopes.sort(cmp=cmpf_w) res = 1 holdlist = [] dic = {} for i in range(len(envelopes)): flag = False for j in range(res,-1,-1): if j not in dic: continue elif dic[j]>= envelopes[i][1]: continue else: flag = True res = max(res,j+1) holdlist.append([j+1,envelopes[i][1]]) break if flag == False: holdlist.append([1,envelopes[i][1]]) if i == len(envelopes) - 1 or envelopes[i][0] < envelopes[i+1][0]: for k in holdlist: if k[0] not in dic: dic[k[0]] = k[1] else: dic[k[0]] = min(dic[k[0]],k[1]) holdlist = [] #print dic return res