代码随想录算法训练营第四十六天 |动态规划part13
647 回文子串
-
确定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 最长回文子序列
-
确定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]