647. 回文子串
1.题目
给定一个字符串,你的任务是计算这个字符串中有多少个回文子串。
具有不同开始位置或结束位置的子串,即使是由相同的字符组成,也会被视作不同的子串。
2.实现
困难点:初次接触这类dp题解决回文字符串,想到假设dp[i][j]为开头i,结尾j的字符串是否为回文字符串,但不知道如何推导递推公式
class Solution:
def countSubstrings(self, s: str) -> int:
# dp[i][j]标记以下标i开头,以下标j结尾的字符串是否为回文串 (j >= i)
n = len(s)
dp = [[0]*n for _ in range(n)]
res = 0
for i in range(n-1, -1, -1):
for j in range(i, n):
if s[i] == s[j]:
if j - i <= 1:
dp[i][j] = 1
res += 1
else:
if dp[i + 1][j - 1]:
dp[i][j] = 1
res += 1
return res
小结:
深刻理解遍历顺序,别又忽略了!
516.最长回文子序列
1.题目
给定一个字符串 s ,找到其中最长的回文子序列,并返回该序列的长度。
2.实现
区别于上题,需讨论一段字符串是否为回文串,这里是统计最长长度,所以只需继承一段字符串记录的最长回文子序列长度
class Solution:
def longestPalindromeSubseq(self, s: str) -> int:
n = len(s)
dp = [[0]*n for _ in range(n)]
res = 0
for i in range(n-1, -1, -1):
for j in range(i + 1, n):
if s[i] == s[j]:
if i == j:
dp[i][j] = 1
# 下面两种情况可以统一一下:
elif j - i == 1:
dp[i][j] = 2
else:
dp[i][j] = dp[i + 1][j - 1] + 2
else:
dp[i][j] = max(dp[i + 1][j], dp[i][j - 1])
res = max(res, dp[i][j])
return res
动态规划总结篇
重点二刷专题:
背包问题:确定遍历顺序
子序列问题:dp定义 和 推导递推公式
二刷时再补充心得体会!
文章讲解