647. 回文子串

109 阅读1分钟

难度: 中等

题目描述

给你一个字符串 s ,请你统计并返回这个字符串中 回文子串 的数目。

回文字符串 是正着读和倒过来读一样的字符串。

子字符串 是字符串中的由连续字符组成的一个序列。

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

示例

输入: s = "aaa"
输出: 6
解释: 6个回文子串: "a", "a", "a", "aa", "aa", "aaa"

解题思路

题解1:中心扩展法

  • 情况1:枚举选定单点 选定单点a,当向两边扩散时注意边界情况,和扩散值是否相等,再统计字串数量 a---->b a b---->c b a b c
  • 情况1:枚举选定双点 选定双点a a,当向两边扩散时注意边界情况,和扩散值是否相等,再统计字串数量 a a---->b a a b---->c b a a b c

Code

class Solution {
public:
    int countSubstrings(string s) {
        int n=s.size();
        int ans=0;
        for(int i=0;i<n;i++){
            int  left=i,right=i;
            while(left>=0&&right<n){
                if(s[left]==s[right])ans++,left--,right++;
                else break;
            }
            left=i-1,right=i;
            while(left>=0&&right<n){
                if(s[left]==s[right])ans++,right++,left--;
                else break;
            }  
        }
        return ans;
    }
};

算法复杂度: 时间复杂度O(N2):O(N^2) 空间复杂度:O(1): O(1)

题解二:动态规划dp[i][j]表示从下标i to j 是否为回文子串,类型为boolean

  • 设置状态转移方程 当s[i]==s[j] 时,分情况讨论

(1)当j-i<2时,既i、j为同一位置或者相邻,此时dp[i][j]=true

(2)否则dp[i][j]=dp[i+1][j-1]

Code

class Solution {
public:
    int countSubstrings(string s) {
        int n=s.size(),ans=0;
        vector<vector<bool>>dp(n,vector<bool>(n,false));
        for(int i=0;i<n;i++){
            for(int j=0;j<=i;j++){
                if(s[i]==s[j]&&((i-j)<2||dp[j+1][i-1]))dp[j][i]=true;
                if(dp[j][i])ans++;
            }
        }
        return ans;
    }
};

算法复杂度: 时间复杂度O(N2):O(N^2) 空间复杂度:O(N2): O(N^2)