• 博客园logo
  • 会员
  • 周边
  • 新闻
  • 博问
  • 闪存
  • 众包
  • 赞助商
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
fangleSea
博客园    首页    新随笔    联系   管理    订阅  订阅
代码随想录|动态规划 - 子序列系列
300.最长递增子序列 

674. 最长连续递增序列 

718. 最长重复子数组  

1143.最长公共子序列 

1035.不相交的线   

53. 最大子序和  动态规划


300.最长递增子序列

dp[i]:以nums[i]为尾的最大上升子序列

如果前面的nums[j]<nums[i] : 

 dp[i] = max(dp[i], dp[j]+1)
初始化:dp[i] = 1
从前向后进行递归
class Solution:
    def lengthOfLIS(self, nums: List[int]) -> int:
        n = len(nums)
        dp = [1 for _ in range(n)]
        ans = 1
        for i in range(n):
            for j in range(i+1):
                if nums[j] < nums[i]:
                    dp[i] = max(dp[i], dp[j]+1)
            if dp[i] > ans:
                ans = dp[i]
        return ans

 


674. 最长连续递增序列

dp[i]: 以nums[i]结尾的最长连续增序列

if nums[i] > nums[i-1] : dp[i] = dp[i-1]+1

初始化:nums[i] = 1

从前向后查找

class Solution:
    def findLengthOfLCIS(self, nums: List[int]) -> int:
        n = len(nums)
        dp = [1 for _ in range(n)]
        ans = 1
        for i in range(1, n):
            if nums[i] > nums[i-1]:
                dp[i] = dp[i-1]+1
            if ans < dp[i]:
                ans = dp[i]
        return ans

 


718. 最长重复子数组

dp[i][j] 以nums1[i]和nums2[j]结尾的最长的重复子数组

if nums1[i-1] == nums[j-1] : dp[i][j] = dp[i-1][j-1]+1

从小到大进行

class Solution:
    def findLength(self, nums1: List[int], nums2: List[int]) -> int:
        n = len(nums1)
        m = len(nums2)
        dp = [[0 for _ in range(m+1)]for _ in range(n+1)]
        ans = 0
        for i in range(1, n+1):
            for j in range(1, m+1):
                if nums1[i-1] == nums2[j-1]:
                    dp[i][j] = dp[i-1][j-1]+1
                ans = max(ans, dp[i][j])
        return ans

 


1143.最长公共子序列

这题我觉得最重要的是推导当text1[i-1] != text2[j-1]的时候dp公式,注意在我们思考二维的时候可以画2*2的格子去确定哪个是我们需要的数据

class Solution:
    def longestCommonSubsequence(self, text1: str, text2: str) -> int:
        n = len(text1)
        m = len(text2)
        np = [[0 for _ in range(m+1)]for _ in range(n+1)]
        for i in range(1, n+1):
            for j in range(1, m+1):
                if text1[i-1] == text2[j-1]:
                    np[i][j] = np[i-1][j-1] + 1
                else:
                    np[i][j] = max(np[i-1][j], np[i][j-1])
        return np[n][m]

 


1035.不相交的线

和上一题一模一样,只不过换了一种说法。不相交的话就是相当于顺序上的最大重合

class Solution:
    def maxUncrossedLines(self, nums1: List[int], nums2: List[int]) -> int:
        n = len(nums1)
        m = len(nums2)
        dp = [[0 for _ in range(m+1)]for _ in range(n+1)]
        for i in range(1, n+1):
            for j in range(1, m+1):
                if nums1[i-1] == nums2[j-1]:
                    dp[i][j] = dp[i-1][j-1] + 1
                else:
                    dp[i][j] = max(dp[i-1][j], dp[i][j-1])
        return dp[n][m]

 


53. 最大子序和

一维比较简单,所以不解释了

class Solution:
    def maxSubArray(self, nums: List[int]) -> int:
        # ans = nums[0]
        # ans_now = 0
        # for i in nums:
        #     if ans_now <= 0:
        #         ans_now = i
        #     else:
        #         ans_now += i
        #     ans = max(ans, ans_now)
        # return ans
        n = len(nums)
        dp = [0 for _ in range(n)]
        dp[0] = nums[0]
        ans = nums[0]
        for i in range(1, n):
            dp[i] = max(dp[i-1]+nums[i], nums[i])
            ans = max(dp[i], ans)
        return ans

 

posted on 2023-07-04 01:59  跪求个offer  阅读(47)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2026
浙公网安备 33010602011771号 浙ICP备2021040463号-3