题目链接
回文子串
题目描述
注意点
- s 由小写英文字母组成
- s 由小写英文字母组成
- 1 <= s.length <= 1000
- 具有不同开始位置或结束位置的子串,即使是由相同的字符组成,也会被视作不同的子串
解答思路
- 最初穷举所有的子串判断每个子串是否是回文子串,时间复杂度较高
- 使用动态规划解决本题,dp[i][j]表示(i, j)之间的子串是否是回文子串,对于dp[i][j],如果s.charAt(i)等于s.charAt(j),且dp[i + 1][j - 1]也为true,说明在回文子串(i + 1, j - 1)左右两侧加上了相同的字符,仍为子串,所以dp[i][j]也为true。注意如果(i, j)之间的长度不大于2时,说明此时的子串为a或aa形式,判断s.charAt(i)与s.charAt(j)相等就已经说明dp[i][j]是回文子串
- 由于需要根据(i, j)的子串是否是回文子串判断dp[i][j]是否是回文子串,所以需要从子串长度由小到大进行遍历,先找到短子串是否是回文子串,再推出长子串是否是回文子串
代码
class Solution {
public int countSubstrings(String s) {
int res = 0;
int n = s.length();
boolean[][] dp = new boolean[n][n];
for (int len = 1; len <= n; len++) {
for (int i = 0; i <= n - len; i++) {
int j = i + len - 1;
if (s.charAt(i) == s.charAt(j) && (len <= 2 || dp[i + 1][j - 1])) {
dp[i][j] = true;
res++;
}
}
}
return res;
}
}
关键点
- 动态规划的思想