返回

剑指 Offer II 020. 回文子字符串的个数

后端

剑指 Offer II 020. 回文子字符串的个数

题目

给定一个字符串 s ,请计算这个字符串中有多少个回文子字符串。

具有不同开始位置或结束位置的子串,即使是由相同的字符组成,也会被视作不同的子串。

示例:

输入:"abc"
输出:3
解释:三个回文子串是 "a", "b", "c"
输入:"aaa"
输出:6
解释:6个回文子串是 "a", "a", "a", "aa", "aa", "aaa"

算法思路:

动态规划。

定义一个二维数组 dp,其中 dp[i][j] 表示字符串 s[i, j] 是否是一个回文子串。

对于每个子串 s[i, j],我们可以通过判断 s[i] 是否等于 s[j] 来判断它是否是一个回文子串。

如果 s[i] 等于 s[j],那么我们只需要判断 s[i+1, j-1] 是否是一个回文子串。

如果 s[i+1, j-1] 也是一个回文子串,那么 s[i, j] 也是一个回文子串。

否则,s[i, j] 不是一个回文子串。

如果 s[i] 不等于 s[j],那么 s[i, j] 不是一个回文子串。

代码实现:

public int countSubstrings(String s) {
    int n = s.length();
    boolean[][] dp = new boolean[n][n];
    int count = 0;

    for (int i = n - 1; i >= 0; i--) {
        dp[i][i] = true;
        count++;

        for (int j = i + 1; j < n; j++) {
            if (s.charAt(i) == s.charAt(j)) {
                if (j - i <= 2 || dp[i + 1][j - 1]) {
                    dp[i][j] = true;
                    count++;
                }
            }
        }
    }

    return count;
}

复杂度分析:

  • 时间复杂度:O(n^2),其中 n 是字符串 s 的长度。
  • 空间复杂度:O(n^2),其中 n 是字符串 s 的长度。

总结:

这道题考察了动态规划的思想。我们可以通过定义一个二维数组 dp 来记录每个子串是否是一个回文子串,然后通过判断 s[i] 是否等于 s[j] 来判断 s[i, j] 是否是一个回文子串。

如果 s[i] 等于 s[j],那么我们只需要判断 s[i+1, j-1] 是否是一个回文子串。

如果 s[i+1, j-1] 也是一个回文子串,那么 s[i, j] 也是一个回文子串。

否则,s[i, j] 不是一个回文子串。

如果 s[i] 不等于 s[j],那么 s[i, j] 不是一个回文子串。

通过这种方法,我们可以求出字符串 s 中所有的回文子字符串的个数。