day56 动态规划part13 代码随想录算法训练营 300. 最长递增子序列

题目:300. 最长递增子序列

我的感悟:

  • 之前做过,都忘记了,这次好好记思路

理解难点:

  • dp[i] 是由昨天的历史遍历后,得到今天的值
  •  

听课笔记:

我的代码:

class Solution:
    def lengthOfLIS(self, nums: List[int]) -> int:
        # 难点是dp的推导公式,
        # dp[i]是截止到nums[i]结尾的最长递增序列的个数
        # dp[i] = if dp[i]> dp[j] max(dp[i],dp[j]+1)    # j 取 0~i
        # 初始值均为1
        dp = [1] * len(nums)
        for i in range(1,len(nums)):
            for j in range(0,i):
                if nums[i] > nums[j]:
                    dp[i] = max(dp[i],dp[j]+1)
        return max(dp)

通过截图:

进一步优化的代码:

class Solution:
    def lengthOfLIS(self, nums: List[int]) -> int:
        if len(nums) <= 1:
            return len(nums)
        dp = [1] * len(nums)
        result = 1
        for i in range(1, len(nums)):
            for j in range(0, i):
                if nums[i] > nums[j]:
                    dp[i] = max(dp[i], dp[j] + 1)
            result = max(result, dp[i]) #取长的子序列
        return result

贪心的写法:

class Solution:
    def lengthOfLIS(self, nums: List[int]) -> int:
        if len(nums) <= 1:
            return len(nums)
        
        tails = [nums[0]]  # 存储递增子序列的尾部元素
        for num in nums[1:]:
            if num > tails[-1]:
                tails.append(num)  # 如果当前元素大于递增子序列的最后一个元素,直接加入到子序列末尾
            else:
                # 使用二分查找找到当前元素在递增子序列中的位置,并替换对应位置的元素
                left, right = 0, len(tails) - 1
                while left < right:
                    mid = (left + right) // 2
                    if tails[mid] < num:
                        left = mid + 1
                    else:
                        right = mid
                tails[left] = num
        
        return len(tails)  # 返回递增子序列的长度

查找的写法:

class Solution:
    def lengthOfLIS(self, nums: List[int]) -> int:
        stack = []
        for num in nums:
            idx = bisect_left(stack, num) # 引入 bisect 查找函数,找num在stack的哪个位置,如果相同就返回它的左边           
            if idx == len(stack):   # 如果找的0就把num放到0的位置,保持stack一直为最小的递增子序列
                stack.append(num)   # 序列相等就加入到列表里
            else:
                stack[idx] = num    # 不相等就替换、
        return len(stack)

资料:

300.最长递增子序列 

今天开始正式子序列系列,本题是比较简单的,感受感受一下子序列题目的思路。 

视频讲解:https://www.bilibili.com/video/BV1ng411J7xP

https://programmercarl.com/0300.%E6%9C%80%E9%95%BF%E4%B8%8A%E5%8D%87%E5%AD%90%E5%BA%8F%E5%88%97.html

posted @ 2024-03-05 14:12  o蹲蹲o  阅读(1)  评论(0编辑  收藏  举报