一.先介绍一下回文串问题
回文串通俗来讲就是正着读反着读得到的结果一样,其中0位置与n-1位置相同、1位置与n-2位置相同以此类推,这条经验也是回文串问题的重要判断条件。接下来我介绍几种特殊的回文串。
二.题目介绍
题目所求是字符串s中有多少子串是回文串,这里子串的概念和子数组一致,是在题目给出的字符串中找出一段有顺序的、连续的子字符串。
三.状态分析
这里注意两个细节:1.填表顺序,我在"最长等差数列"一题总结过,填表顺序是由状态方程决定的,本题的状态方程为:dp[ i ][ j ] = dp[ i+1][ j-1],i 位置决定填表顺序是由下到上,j 位置决定填表顺序是由左到右的,2.遍历顺序,遍历顺序通常是我们设定状态时同时确定的隐藏条件,比如本题的回文串,i 表示首元素的位置,j 表示尾元素的位置,始终 i <= j 的,所以 j的遍历顺序是从 i-1到 n-1位置。
四.完整代码
int countSubstrings(string s)
{
int n = s.size(), res = 0;
vector<vector<bool>> dp(n, vector<bool>(n));
for(int i = n-1; i >= 0; i--)
{
for(int j = i; j < n; j++)
//这里下标有一个默认规律:i<=j,所以这就确定了j的遍历是在i之后遍历
{
if(s[i] == s[j])
{
if(i+1 < j)
dp[i][j] = dp[i+1][j-1];
else
dp[i][j] = true;
if(dp[i][j])
res += 1;
}
}
}
return res;
}