代码随想录算法训练营第四十六天 |动态规划part13(动态规划完)

14 阅读2分钟

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

647 回文子串

image-20250124215408147.png

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

    • dp[i] [j] 表示[i-j]范围内是不是一个回文串
  • 递推公式

    • if s[i] == s[j]:

      情况1,j == i == 1 ,例如 a

      情况2,j - i = 1,例如 aa

      情况3,j - i > 1 , 需要判断i+1 和 j-1 这段区间是不是回文串 dp[i+1] [j-1] == True

      if j - i <= 1:

      dp[i] [j] == True

      result += 1

      elif dp[i+1] [j-1]:

      dp[i] [j] == True

      result += 1

  • dp数组如何初始化

    • dp = [[False]*(len(s)+1)]
  • 遍历顺序

    • 左下 -> 右上

    • for i in range(len(s)-1,-1,-1):

      for j in range(i,len(s))

  • 打印dp数组

    • return result
dp = [[False] * len(s) for _ in range(len(s))]
result = 0
for i in range(len(s)-1,-1,-1):
    for j in range(i,len(s)):
        if s[i] == s[j]:
            if j - i <= 1:
                dp[i][j] = True
                result += 1
            elif dp[i+1][j-1]:
                dp[i][j] = True
                result += 1
return result

516 最长回文子序列

image-20250124215416712.png

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

    • dp[i] [j] 表示[i-j]范围内回文子序列的长度为dp[i] [j]
  • 递推公式

    • if s[i] == s[j]:

      dp[i] [j] = dp[i+1] [j-1] +2

      else :

      把s[i]加进来,此时子串为 [i ,j - 1],此时回文子序列的长度为dp[i] [j-1]

      把s[j]加进来,此时子串为 [i +1,j ],此时回文子序列的长度为dp[i+1] [j]

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

  • dp数组如何初始化

    • dp = [[0] * len(s) for _ in range(len(s))]
    • dp[i] [i] = 1
  • 遍历顺序

    • for i in range(len(s)-1, -1, -1):

      for j in range(i+1, len(s)):

      (j一定从i+1开始,因为j>i)

  • 打印dp数组

    • return dp[0] [-1]
dp = [[0]*len(s) for i in range(len(s))]
for i in range(len(s)):
    dp[i][i] = 1
for i in range(len(s)-1,-1,-1):
    for j in range(i+1,len(s)):
        if s[i] == s[j]:
            dp[i][j] = dp[i+1][j-1] + 2
        else :
            dp[i][j] = max(dp[i+1][j],dp[i][j-1])
return dp[0][-1]

总结

img