目录
647. 回文子串
516.最长回文子序列
动态规划总结篇
647. 回文子串
dp数组的定义
dp[i][j]代表的是区间[i,j]的字串是否为回文字符,如果dp[i][j]为true,否则为false
递推公式
如果s[i]和s[j]相等的话
1.i==j
为同一个字符,dp[i][j] = True
2 i与j相差1
dp[i][j] = True
3.i与j相差大于1
看一下前面的区间是不是true
dp[i-1][j-1] == True
如果不相等,那么return false
初始化
dp[i][j]== False
遍历顺序
因为需要在相等的第三种情况,需要判断里面的区间是不是回文。但是如果从上往下,从左往右遍历的话,会直接使用dp[i+1][j-1]未初始化的情况。所以我们不能那么遍历,所以我们需要从下往上,从左往右遍历
class Solution:
def countSubstrings(self, s: str) -> int:
#dp数组的定义,dp[i][j]
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]:
#i==j
if i == j:
result += 1
dp[i][j] = True
elif j-i == 1:
result += 1
dp[i][j] = True
else:
if dp[i+1][j-1]:
result += 1
dp[i][j] = True
return result
代码随想录
516.最长回文子序列
dp数组的定义
dp[i][j]指的是字符串在[i,j]范围内最长回文子序列的长度是dp[i][j]
递归公式
如果s[i]和s[j]相同:
就要把长度+2,因为加入新的两个数
dp[i][j] = dp[i-1][j-1]+2
如果不相同:
那么把s[i]放进去
dp[i][j]= dp[i][j-1]
把s[j]放进去
dp[i][j]= dp[i-1][j]
初始化
如果i==j的话,一定是等于1的
遍历顺序
从下到上,从左到右
打印dp
最后返回就看i,j区间内,最长的长度
647. 回文子串,求的是回文子串,而本题要求的是回文子序列, 大家要搞清楚两者之间的区别。
代码随想录
class Solution:
def longestPalindromeSubseq(self, s: str) -> int:
#dp数组的定义
dp = [[0]*len(s) for _ 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)):
#如果s[i]==s[j]的话
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]
动态规划总结篇
代码随想录