给定一个字符串,你的任务是计算这个字符串中有多少个回文子串。
具有不同开始位置或结束位置的子串,即使是由相同的字符组成,也会被视作不同的子串。
示例 1:
输入:“abc”
输出:3
解释:三个回文子串: “a”, “b”, “c”
示例 2:
输入:“aaa”
输出:6
解释:6个回文子串: “a”, “a”, “a”, “aa”, “aa”, “aaa”
dpij是i到j是否是回文串;
这个题的话首先看最特殊的情况,就是全部字母都不一样的时候有 的是长度为1的回文串
然后再看长度为2的时候的回文串的个数,这个时候的回文串的个数就是看si 和sj等不等,
然后看长度为3的串是不是回文串还是是si和sj的关系,
当长度为4的时候就不一样了,不仅要看si和sj等不等,等的话还要看dpi+1和dpj-1等不等,同时相等才有dpi和dpj为回文串,
一次类推,到长度为n的时候就是他最长的回文串了
所以动态方程就出来了
dp[i][j] = (dp[i+1][j-1]&&s[i]s[j]);j>1
dp[i][j] = s[i] ==s[j] j<=1
解题思路
此处撰写解题思路
因为是子串,所以不能单独把某一个字符拿出看看,所以我们要有整体性的思路来想.
1:单独一个字符算一个子串
2:如果是两个字符的时候 如果si=="sj那么他也是子串
3:当有两个以上的字符的时候,如果si=="sj那么就看i+1和j-1这一段是不是回文串,如果是那么i,j就是回文串,回文串个数就能加1,否则就不是,就不能加1.并且dpij = false.
代码
class Solution {
public:
int countSubstrings(string s) {
int len =s.size();
bool dp[len+1][len+1];
dp[0][0] =false;
int maxn =0;
for(int l =0;l<len ;l++)
{
for(int i=0;i+l<len;i++)
{
int j= i+l;
if(i==j)
{
dp[i][j] = 1;
maxn++;
}
else if(j-i==1)
{
if(s[i]==s[j])
{
dp[i][j] =1;
maxn++;
}
else
{
dp[i][j] =false;
}
}
else
{
if(s[i] ==s[j]&&dp[i+1][j-1]==true)
{
dp[i][j] = true;
maxn++;
}
else
{
dp[i][j] =false;
}
}
//cout<<i<<" "<<j<<" "<<dp[i][j]<<endl;
}
}
return maxn ;
}
};