给你一个字符串 s ,请你统计并返回这个字符串中 回文子串 的数目。
回文字符串 是正着读和倒过来读一样的字符串。
子字符串 是字符串中的由连续字符组成的一个序列。
具有不同开始位置或结束位置的子串,即使是由相同的字符组成,也会被视作不同的子串。
题解
动态规划步骤:
1.确定dp[i][j]含义:字符串s[i:j]是否为回文字符串
2. 动态转移方程:
如果s[i]=s[j],才可能为回文串,继续判断j-i的长度
(1)如果 j-i == 0 字符串长度为1,为回文
(2) 如果j-i==1 此时字符串长度为2,为回文串
(3)如果j-i>=2 dp[i][j]=dp[i+1][j-1](根据子串判断当前串)
3.初始值:最开始默认为false
4.遍历顺序:因为计算dp[i][j]时,要用到dp[i+1][j-1],所以要从下到上,从左至右遍历
5.返回值.如果(dp[i][j]==true) ans++ 返回最终的ans
注意
遍历顺序:因为计算dp[i][j]时,要用到dp[i+1][j-1],所以要从下到上,从左至右遍历
class Solution {
//dp[i][j]存储是否回文
//如果dp[i][j]为true,ans++
public int countSubstrings(String s) {
int len=s.length();
char[] c = s.toCharArray();
int ans=0;
boolean[][] dp = new boolean[len][len];
//注意遍历顺序:因为计算dp[i][j]时,要用到dp[i+1][j-1]
//所以要从下到上,从左至右遍历
for(int i=len-1;i>=0;i--){
for(int j=i;j<=len-1;j++){
//两端相同
if(c[i]==c[j]){
//2.为什么dp[i+1][j-1]没有越界?
//因为计算dp[len-1][j]时,j的值只可能为len-1
//满足j-i<=1,不会进入dp[i+1][j-1]
//3.j-i<=1包括 1)j=i dp[i][i]=true 2)dp[i][i+1]=true
//4.若j-i>=3 则需要判断中间的数组是否为回文数组
dp[i][j]=(j-i<=1)||dp[i+1][j-1];
}
if(dp[i][j]==true) ans++;
}
}
return ans;
}
}