力扣300题、354题(最长递增子序列,信封嵌套)

300、最长递增子序列

第一种方法

基本思想:

动态规划

具体实现:

1、确定状态

(1)最后一步---以nums[i]这个数结尾的最长递增子序列的长度,设为dp[i]

(2)化为子问题---比nums[i]小的之前的nums为结尾的最长递增子序列的长度

2、转移方程

dp[i] = max(dp[i], dp[j] + 1)

3、初始条件和边界条件

dp初始化都为1

4、计算顺序

从前往后

代码:

# Dynamic programming.
class Solution:
    def lengthOfLIS(self, nums: List[int]) -> int:
        if not nums: return 0
        dp = [1] * len(nums)
        for i in range(len(nums)):
            for j in range(i):
                if nums[j] < nums[i]: # 如果要求非严格递增,将此行 '<' 改为 '<=' 即可。
                    dp[i] = max(dp[i], dp[j] + 1)
        return max(dp)

 

第二种方法:

基本思想:

二分搜索

具体实现:

书101页

while处是left<right

说明是开区间,right的值在top中刚开始总是top的长度

代码:

class Solution:
    def lengthOfLIS(self, nums: List[int]) -> int:
        top = [0]*len(nums)
        piles = 0
        for i in range(len(nums)):
            poker = nums[i]
            left = 0
            right = piles
            while left<right:
                mid = (left+right)//2
                if top[mid]>poker:
                    right = mid
                elif top[mid]<poker:
                    left = mid + 1
                else:
                    right = mid
            if left == piles:
                piles += 1
            top[left] = poker
        return piles

 

 

 

354、信封嵌套问题

基本思想:

动态规划

具体实现:

先对宽度w进行升序排序,如果遇到w相同的情况,则按照高度降序排序。

之后把h作为一个数组,在这个数组上计算出的最长递增子序列就是答案。

envelopes = [[1,8],[2,3],[5,4],[5,2]]

envelopes[1] = [2,3]

envelopes[1][1] =[3]

envelopes[j][1] =每个数组的第二个数

代码:

class Solution:
    def maxEnvelopes(self, envelopes: List[List[int]]) -> int:
        if not envelopes:
            return 0
        
        n = len(envelopes)
        envelopes.sort(key=lambda x: (x[0], -x[1]))
        # x[0]代表按第一个维度行来升序排序,再-x[1]代表在行排序的基础上对列降序排序

        f = [1] * n
        for i in range(n):
            for j in range(i):
                if envelopes[j][1] < envelopes[i][1]:
                    f[i] = max(f[i], f[j] + 1)
        
        return max(f)

 第二种方法:

class Solution:
    def maxEnvelopes(self, envelopes: List[List[int]]) -> int:
        if not envelopes:
            return 0
        top = [1]*len(envelopes)
        envelopes.sort(key = lambda x:(x[0],-x[1]))
        piles = 0
        for i in range(len(envelopes)):
            left, right = 0, piles
            poker = envelopes[i][1]
            while left < right:
                mid = (left + right)//2
                if top[mid] > poker:
                    right = mid
                elif top[mid] < poker:
                    left = mid+1
                else:
                    right = mid
            if left == piles:
                piles += 1
            top[left] = poker
        return piles

 

posted @ 2021-03-11 18:40  最近饭吃的很多  阅读(84)  评论(0编辑  收藏  举报