class Solution {
public:
bool valid(string& s, int first, int end) {
for (int i = first, j = end; i < j; i++, j--)
if (s[i] != s[j]) return false;
return true;
}
int countSubstrings(string s) {
int count = 0;
for (int i = 0; i < s.size(); i++)
for (int j = i; j < s.size(); j++)
if (i == j || valid(s, i, j)) count++;
return count;
}
};
【dp
数组含义】表示区间范围s[i,j]
的子串是否是回文子串,如果是dp[i][j]
为true
,否则为false
当s[i] == s[j]
时有如下两种情况
1
个字符或2
个相邻字符s[i+1, j-1]
内是否回文串class Solution { // 动态规划
public:
int countSubstrings(string s) {
int size = s.size();
int count = 0;
vector<vector<bool>> dp(size, vector<bool>(size, false));
// 由于dp[i + 1][j - 1]是左下方值,因此需要按右上方遍历
for (int i = size - 1; i >= 0; i--)
for (int j = i; j < size; j++) {
// 1.两字符相同则继续
if (s[i] != s[j]) continue;
// 2.共1个字符或2个相邻字符
if (j - i <= 1) {
count++;
dp[i][j] = true;
// 3.多个字符则需要判断s[i+1, j-1]内是否回文串
} else if (dp[i + 1][j - 1]) {
count++;
dp[i][j] = true;
}
}
return count;
}
};
【注意事项】一个元素为中心点
+ 两个元素为中心点
进行左右扩展
class Solution {
public:
int extend(string& s, int c1, int c2) {
int count = 0;
while (c1 >= 0 && c2 < s.size() && s[c1] == s[c2]) {
c1--;
c2++;
count++;
}
return count;
}
int countSubstrings(string s) {
int count = 0;
for (int i = 0; i < s.size(); i++) {
count += extend(s, i, i); // 以单点为中心进行左右扩展
count += extend(s, i, i + 1); // 以双点为中心进行左右扩展
}
return count;
}
};