leetcode 647. 回文子串

题目描述:

给定一个字符串,你的任务是计算这个字符串中有多少个回文子串。

具有不同开始位置或结束位置的子串,即使是由相同的字符组成,也会被视作不同的子串。

示例 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,我们可以把可能的回文中心列出来:

leetcode 647. 回文子串_第1张图片

可以看出长度为 n 的字符串会生成 2n-1组回文中心,回文中心左起始位置l=i//2,右结束位置为r=l+i mod 2。这样我们只要从 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

 

你可能感兴趣的:(leetcode,字符串,leetcode,字符串)