0 前言
今天开一个新的专题,做leetcode刷题的讲解,其目的是对每个题目进行精打细磨,以加深理解,触类旁通。
后期会按照题型进行归类整理。
1 思路解析
本题考虑使用dp动态规划来解。
1.1 dp数组
二维数组dp[i][j]表示区间[i,j]范围内的子串是否为回文串,是则为true,否则为false。
1.2 dp状态转移方程
s[i] == s[j]时:
- 若i == j,例"a"、"b"则必然为回文子串,此时dp[i][j]为true;
- 若i与j相邻,例如"aa"、"bb"也是回文子串,此时dp[i][j]为true;
- 若i与j不再相邻,例如"abca"、“aba”、“abba”,此时需要根据s[i+1]和s[j-1]进行判断,或者根据dp[i+1][j-1],若其为true,则表示i和j之间的子串满足回文子串。
即:
if (s[i] == s[j]) {
if (j - i <= 1) {// 情况一:i == j 情况二:i与j相差1
ans++;
dp[i][j] = true;
} else if (dp[i+1][j-1]) {// 情况三:i与j相差2个以上元素-->此时需要根据s[i+1]和s[j-1]进行判断
ans++;
dp[i][j] = true;
}
}
1.3 dp初始化
dp[n][n]数组默认为false。
2 完整代码
本题完整代码如下:
int countSubstrings(string s) {
int n = s.size();
int ans = 0;
vector<vector<bool>> dp(n, vector<bool>(n, false));
for (int i = n - 1; i >= 0 ;i--) {
for (int j = i; j < n; j++) {
if (s[i] == s[j]) {
if (j - i <= 1) {// 情况一:i == j 情况二:i与j相差1
ans++;
dp[i][j] = true;
} else if (dp[i+1][j-1]) {// 情况三:i与j相差2个以上元素-->此时需要根据s[i+1]和s[j-1]进行判断
ans++;
dp[i][j] = true;
}
}
}
}
return ans;
}