代码随想录算法训练营第四十三天 |动态规划part10

24 阅读2分钟

代码随想录算法训练营第四十三天 |动态规划part10

300 最长递增子序列

image-20250122220039530.png

  • 确定dp数组以及下标的含义

    • dp[i] : 以nums[i]结尾的最长递增子序列的长度
  • 递推公式

    • dp[j] : 以nums[j]结尾的最长递增子序列的长度
    • 如果 nums[j] < nums[i] , 那么 dp[i] = max(dp[j] + 1,dp[i]) (其中j<i)
  • dp数组如何初始化

    • dp[i] = 1
  • 遍历顺序

    • for i in range(1,len(nums)):

      for j in range(i)

  • 打印dp数组

    • return max(dp)
n = len(nums)
dp = [1] * n
for i in range(1,n):
    for j in range(i):
        if nums[j] < nums[i]:
            dp[i] = max(dp[i],dp[j]+1)
return max(dp)

674 最长连续递增序列

image-20250122220104656.png

if len(nums) == 0:
    return 0
result = 1
dp = [1] * len(nums)
for i in range(len(nums)-1):
    if nums[i+1] > nums[i]: #连续记录
        dp[i+1] = dp[i] + 1
    result = max(result, dp[i+1])
return result

贪心算法:

if len(nums) == 0:
    return 0
result = 1 #连续子序列最少也是1
count = 1
for i in range(len(nums)-1):
    if nums[i+1] > nums[i]: #连续记录
        count += 1
    else: #不连续,count从头开始
        count = 1
    result = max(result, count)
return result

718 最长重复子数组

image-20250122220113116.png

  • 确定dp数组以及下标的含义

    • dp[i] [j] : 以i-1结尾的nums1 和以 j-1结尾的nums2这两个数组的最长重复子数组的长度
  • 递推公式

    • if nums1[i-1] == nums2[j-1] : dp[i] [j] = dp[i-1] [j-1] + 1
  • dp数组如何初始化

    • dp[i] [0] dp[0] [j] 都初始化为0
    • 可以全初始化为0
    •   dp = [[0] * (len(nums2) + 1) for _ in range(len(nums1) + 1)]
      
  • 遍历顺序

    • for i in range(1,len(nums1)+1):

      for j in range(1,len(nums2)+1)

  • 打印dp数组

dp = [[0] * (len(nums2)+1) for _ in range(len(nums1)+1)]
result = 0
for i in range(1,len(nums1)+1):
    for j in range(1,len(nums2)+1):
        if nums1[i-1] == nums2[j-1]:
            dp[i][j] = dp[i-1][j-1] + 1
        if dp[i][j] > result :
            result = dp[i][j]
return result