647. 回文子串
1. doc reading
class Solution:
def countSubstrings(self, s: str) -> int:
s = list(s)
dp = [[False] * len(s) for _ in range(len(s))]
count = 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:
dp[i][j] = True
elif j == i + 1:
dp[i][j] = True
else:
dp[i][j] = dp[i + 1][j - 1]
if dp[i][j]:
count += 1
return count
- 注意递推顺序
- 另外,一般dp都是求什么是什么,但是回文串这个不行,因为求什么是什么难以继续递推。
516. 最长回文子序列
1. doc reading
如果s[i]与s[j]不相同,说明s[i]和s[j]的同时加入 并不能增加[i,j]区间回文子序列的长度,那么分别加入s[i]、s[j]看看哪一个可以组成最长的回文子序列。
加入s[j]的回文子序列长度为dp[i + 1][j]。
加入s[i]的回文子序列长度为dp[i][j - 1]。
那么dp[i][j]一定是取最大的,即:dp[i][j] = max(dp[i + 1][j], dp[i][j - 1]);
如果s[i]与s[j]相同,那么dp[i][j] = dp[i + 1][j - 1] + 2;
class Solution:
def longestPalindromeSubseq(self, s: str) -> int:
dp = [[0] * len(s) for _ in range(len(s))]
max_len = 0
for i in range(len(s) - 1, -1 , -1):
for j in range(i, len(s)):
if s[i] == s[j]:
if (i == j):
dp[i][j] = 1
elif (i + 1 == j):
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])
max_len = max(max_len, dp[i][j])
# print(dp)
return max_len