python
class Solution:
def countSubstrings(self, s: str) -> int:
n = len(s)
# dp[i][j] 表示字符串i到j是否是回文串
dp = [[False] * (n + 1) for _ in range(n + 1)]
res = 0 # 记录数量
# 遍历顺序从下到上,左到右,由依赖决定
# dp[i][j]的值和dp[i + 1][j - 1]有关
for i in range(n - 1, -1, -1):
for j in range(i, n):
if s[i] == s[j]:
if j - i <= 1:
# 当子串长度小于等于2时,两端相等就是回文串
dp[i][j] = True
res += 1
elif dp[i + 1][j - 1]:
# 两端相等且中间是回文串的情况
dp[i][j] = True
res += 1
return res
中心扩散优化:
python
class Solution:
def countSubstrings(self, s: str) -> int:
# 中心扩散的方法
n = len(s)
self.res = 0
def extend(i, j):
while i >= 0 and j <= n - 1 and s[i] == s[j]:
self.res += 1
i -= 1
j += 1
for i in range(n):
# 以i为中心奇数长的串
extend(i, i)
# 以i和i + 1为中心偶数长的串
extend(i, i + 1)
return self.res
python
class Solution:
def longestPalindromeSubseq(self, s: str) -> int:
n = len(s)
dp = [[0] * (n) for _ in range(n)]
for i in range(n - 1, - 1, -1):
# 初始化对角线
dp[i][i] = 1
for j in range(i + 1, n):
if s[i] == s[j]:
# 两头相等时,是中间部分的值 + 2
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][n - 1]