LeetCode-647. 回文子串
题目来源
题目详情
给你一个字符串 s
,请你统计并返回这个字符串中 回文子串 的数目。
回文字符串 是正着读和倒过来读一样的字符串。
子字符串 是字符串中的由连续字符组成的一个序列。
具有不同开始位置或结束位置的子串,即使是由相同的字符组成,也会被视作不同的子串。
示例 1:
输入: s = "abc"
输出: 3
解释: 三个回文子串: "a", "b", "c"
示例 2:
输入: s = "aaa"
输出: 6
解释: 6个回文子串: "a", "a", "a", "aa", "aa", "aaa"
提示:
1 <= s.length <= 1000
s
由小写英文字母组成
相似题目
题解分析
解法一:动态规划
- 与【最长回文子串】这题类似,这里也可以使用动态规划的思想来求解回文子串。
- 我们设置状态方程为\(dp[i][j]\),其表示为以(i,j)结尾的子串是否是回文串。状态转移可以表示为:\(dp[i][j] = dp[i+1][j-1] && (s.charAt(i) == s.charAt(j))\)。
- 需要注意的是,在实际编码时,并不是从i为0,j为0开始遍历,而是使用长度l为0开始遍历,二维遍历使用i为0作为起点开始遍历。
class Solution {
public int countSubstrings(String s) {
// dp[i][j]:以i,j结尾的子串是否是回文子串
// dp[i][j] = dp[i+1][j-1] && (s[i+1] == s[j-1])
int n = s.length();
boolean[][] dp = new boolean[n][n];
int ans = 0;
for(int l =0; l<n; l++){
for(int i =0; i + l<n; i++){
int j = i + l;
if(l == 0){
dp[i][j] = true;
}else if(l == 1){
dp[i][j] = (s.charAt(i) == s.charAt(j));
}else{
dp[i][j] = (dp[i+1][j-1] && (s.charAt(i) == s.charAt(j)));
}
if(dp[i][j]){
ans++;
}
}
}
return ans;
}
}
结果展示
Either Excellent or Rusty