题目简介:
给定一个字符串,你的任务是计算这个字符串中有多少个回文子串。
具有不同开始位置或结束位置的子串,即使是由相同的字符组成,也会被视作不同的子串。
示例 1:
1 2 3
| 输入:"abc" 输出:3 解释:三个回文子串: "a", "b", "c"
|
示例 2:
1 2 3
| 输入:"aaa" 输出:6 解释:6个回文子串: "a", "a", "a", "aa", "aa", "aaa"
|
提示:
思路:
动态规划,dp[i][j]
代表s[i ... j]
是否为回文串。
所以我们可以分为三种情况来讨论:
- 一个字符的情况,必为回文串,也就是
dp[i][i] = true
。
- 两个字符的情况,为回文串的条件是
j - i == 1 && s[i] == s[j]
。
- 多于两个字符的情况,为回文串的条件是
j - i > 1 && s[i] == s[j] && dp[i + 1][j - 1]
。
tip:
- 两个字符的情况需要单独拿出来,因为用了
dp[i + 1][j - 1]
,会导致i + 1 > j - 1
。
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| class Solution { public: int countSubstrings(string s) {
if(s.size() == 0) return 0;
vector<vector<bool>> dp(s.size(), vector<bool>(s.size(), false));
for(int i = 0; i < s.size(); i++){
dp[i][i] = true; }
int count = s.size();
for(int j = 0; j < s.size(); j++){
for(int i = 0; i < j; i++){
if(j - i == 1 && s[i] == s[j]){
dp[i][j] = true; count++; } else if(j - i > 1 && s[i] == s[j] && dp[i + 1][j - 1]){
dp[i][j] = true; count++; } } }
return count;
} };
|