给定一个字符串,你的任务是计算这个字符串中有多少个回文子串。
具有不同开始位置或结束位置的子串,即使是由相同的字符组成,也会被视作不同的子串。
示例 1:
输入:"abc"
输出:3
解释:三个回文子串: "a", "b", "c"
示例 2:
输入:"aaa"
输出:6
解释:6个回文子串: "a", "a", "a", "aa", "aa", "aaa"
一个字符串是回文串,它的首尾字符相同,且剩余子串也是一个回文串。因此,求一个字符串是否是回文串可以分解成规模小一点的子问题,它的结果影响大问题的结果。
bool类型数组dp[i][j]表示i和j之间的字符串是否为回文串,可得以下动态转移方程:
dp[i][j]=True if i==j
dp[i][j]=(s[i]==s[j]) if j-i==1
dp[i][j]=dp[i+1][j-1] and (s[i]==s[j]) else
class Solution(object):
def countSubstrings(self, s):
"""
:type s: str
:rtype: int
"""
l,cnt=len(s),0
dp=[[True]*l for _ in range(l)]
for d in range(l): #d在外层循环,从单个字符开始依次扩张查找回文串,否则会出现在判断长字符串时,使用短字符未更新的初始值True,造成结果错误
for x in range(l):
y=x+d #d表示字符串左右位置之间的距离
if y>=l:
break
elif d==1:
dp[x][y]=(s[x]==s[y])
elif x=1:
dp[x][y]=dp[x+1][y-1] and (s[x]==s[y])
if dp[x][y]:
cnt+=1
return cnt
枚举每一个可能的回文中心,然后用两个指针分别向左右两边拓展,当两个指针指向的元素相同的时候就拓展,否则停止拓展。
假设 n = 4,我们可以把可能的回文中心列出来:
可以看出长度为 n 的字符串会生成 2n-1组回文中心,回文中心左起始位置,右结束位置为。这样我们只要从 0到 2n - 2 遍历 i,就可以得到所有可能的回文中心。
class Solution(object):
def countSubstrings(self, s):
"""
:type s: str
:rtype: int
"""
cnt,n=0,len(s)
for i in range(2*n-1):
l,r=i//2,i//2+i%2
while l>=0 and r