LeetCode-647. 回文子串

题目来源

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 由小写英文字母组成

相似题目

  1. 5. 最长回文子串
  2. 647. 回文子串

题解分析

解法一:动态规划

  1. 与【最长回文子串】这题类似,这里也可以使用动态规划的思想来求解回文子串。
  2. 我们设置状态方程为\(dp[i][j]\),其表示为以(i,j)结尾的子串是否是回文串。状态转移可以表示为:\(dp[i][j] = dp[i+1][j-1] && (s.charAt(i) == s.charAt(j))\)
  3. 需要注意的是,在实际编码时,并不是从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;
    }
}

结果展示

image

posted @ 2022-01-07 11:59  Garrett_Wale  阅读(36)  评论(0编辑  收藏  举报