难度: 中等
题目描述
给你一个字符串 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;
}
};
算法复杂度: 时间复杂度 空间复杂度
题解二:动态规划
设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;
}
};
算法复杂度: 时间复杂度 空间复杂度