这道题很经典,也很有重复回味的意义
方法一 动态规划法
动态规划的两个特点:第一大问题拆解为小问题,第二重复利用之前的计算结果,来解答这道题。
我们维护一个二维数组dp,其中dp[i][j]表示字符串区间[i, j]是否为回文串,当i = j时,只有一个字符,肯定是回文串,如果i = j + 1,说明是相邻字符,此时需要判断s[i]是否等于s[j],如果i和j不相邻,即i - j >= 2时,除了判断s[i]和s[j]相等之外,dp[j + 1][i - 1]若为真,就是回文串,通过以上分析,可以写出递推式如下:
dp[i, j] = 1 if i == j
= s[i] == s[j] if j = i + 1
= s[i] == s[j] && dp[i + 1][j - 1] if j > i + 1
代码如下:
class Solution:
def countSubstrings(self, s: str) -> int:
n = len(s)
dp = [[0] * n for m in range(n)]
count = 0
for i in range(n):
for j in range(i):
dp[i][j] = (s[i] == s[j]) & ((i-j < 2) | dp[i-1][j+1])
if dp[i][j] == 1:
count += 1
dp[i][i] = 1
count += 1
return count
方法二 两边扩展法
class Solution:
def countSubstrings(self, s: str) -> int:
def getCount(l,r):
count = 0
while l>=0 and r<n and s[l] == s[r]:
count += 1
l -= 1
r += 1
return count
n = len(s)
count = 0
for i in range(n):
count += getCount(i,i)
count += getCount(i,i+1)
return count
getCount(i,i)和getCount(i,i+1),就是从第i个位置或者第i与i+1个位置开始左右拓展,判断是不是回文串,如果是的话就计数