【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

 

posted @ 2018-09-01 08:29  seyjs  阅读(206)  评论(0编辑  收藏  举报