回文子串-动态规划解法
给定一个字符串 s ,请计算这个字符串中有多少个回文子字符串。
具有不同开始位置或结束位置的子串,即使是由相同的字符组成,也会被视作不同的子串。
示例 1:
输入:s = "abc"
输出:3
解释:三个回文子串: "a", "b", "c"
示例 2:
输入:s = "aaa"
输出:6
解释:6个回文子串: "a", "a", "a", "aa", "aa", "aaa"
提示:
1 <= s.length <= 1000s由小写英文字母组成
题解
这道题我们可以用动态规划进行解题
思路
定义一个二维表,i和j构成
[i,j]区间,每个区间都代表一个子串表格中每个单元都代表一个子串区间,是回文串则这个表做个标记
最终将表格填写完成,统计被标记的单元的个数
状态转移方程:
i>j->dp[i][j]=false
s[i]!=s[j]->dp[i][j]=false
s[i]==s[j] && (i==j||i+1==j)->dp[i][j]=true
s[i]==s[j]&&(i+1<j)->dp[i][j]=dp[i+1][j-1]
_______________________________
| \ i | | | |
| j \ | 1 | | n |
|_____\|_____|___________|______|
| 1 | |
|______|________________________|
| | |
| | |
| | |
| | |
|______|________________________|
| n | |
|______|________________________|
代码部分
CPP
class Solution {
public:
int countSubstrings(string s) {
int len=s.size(); //统计一下这是个多长的字符串
vector<vector<bool>> dp(len,vector<bool>(len,false)); // 顶一个len*len的二维dp表记录回文子串
int ret=0; //定义一个计数器统计回文子串的个数
for(int i=len-1;i>=0;i--)
{
for(int j=i;j<=len-1;j++)
{
if(s[i]==s[j])
{
if(i==j||i+1==j)
{
dp[i][j]=true;
}
else
{
dp[i][j]=dp[i+1][j-1];
}
if(dp[i][j])
{
++ret;
}
}
}
}
return ret;
}
};
- 结果如图
