力扣 回溯法 | LCR 020. 回文子串

ps:图片源于网络,侵删

目录

一、题目

二、代码

三、核心逻辑解析

一、题目

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

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

示例 1:

复制代码
输入:s = "abc"
输出:3
解释:三个回文子串: "a", "b", "c"

示例 2:

复制代码
输入:s = "aaa"
输出:6
解释:6个回文子串: "a", "a", "a", "aa", "aa", "aaa"

提示:

  • 1 <= s.length <= 1000
  • s 由小写英文字母组成

二、代码

java 复制代码
class Solution {
    /**
     * 计算字符串中回文子串的总数
     * @param s 输入的字符串
     * @return 回文子串的数量
     */
    public int countSubstrings(String s) {
        // 边界条件处理:如果字符串为空或长度为0,直接返回0
        if (s == null || s.length() == 0) {
            return 0;
        }
        
        int count = 0; // 初始化回文子串的计数器
        
        // 遍历字符串的每一个字符,将其作为潜在的回文中心
        for (int i = 0; i < s.length(); ++i) {
            // 情况1:以当前字符 s[i] 为单一中心(奇数长度回文,如 "aba")
            // 传入相同的索引 i, i 作为左右起点
            count += countPalindrome(s, i, i);
            
            // 情况2:以当前字符 s[i] 和下一个字符 s[i+1] 为双中心(偶数长度回文,如 "abba")
            // 传入相邻的索引 i, i+1 作为左右起点
            count += countPalindrome(s, i, i + 1);
        }
        
        return count; // 返回最终的统计结果
    }

    /**
     * 从指定的中心位置向两边扩展,统计能形成的回文子串数量
     * @param s 输入的字符串
     * @param start 扩展的左边界起始索引
     * @param end 扩展的右边界起始索引
     * @return 以该中心扩展出的回文子串数量
     */
    private int countPalindrome(String s, int start, int end) {
        int count = 0; // 记录当前中心能找到的回文串个数
        
        // 循环条件:
        // 1. start >= 0 : 左边界不能越界(不能小于0)
        // 2. end < s.length() : 右边界不能越界(不能大于等于字符串长度)
        // 3. s.charAt(start) == s.charAt(end) : 左右两边的字符必须相等
        while (start >= 0 && end < s.length() && s.charAt(start) == s.charAt(end)) {
            // 只要满足上述条件,说明找到了一个新的回文子串
            count++; 
            
            // 继续向两边扩展:左指针左移,右指针右移
            start--;
            end++;
        }
        
        return count; // 返回当前中心找到的回文子串总数
    }
}

三、核心逻辑解析

  1. 为什么循环里要调用两次 countPalindrome?
    因为回文串的长度分为奇数和偶数。
    • 奇数回文(如 "racecar")有一个绝对的中心字符,所以用 (i, i) 扩展。
    • 偶数回文(如 "noon")的中心在两个字符之间,所以用 (i, i+1) 扩展。
  2. 时间复杂度 : O(N2)O(N2) 。外层循环遍历 NN 个字符,内层 while 循环在最坏情况下(比如全由相同字符组成的字符串 "aaaaa")会扩展到边界,耗时 O(N)O(N) 。
  3. 空间复杂度: O(1)O(1) 。只使用了几个整型变量,没有使用额外的数组或哈希表。
相关推荐
她说可以呀6 小时前
Vue插槽
前端·javascript·vue.js
qq_448011166 小时前
Vue + Jinja2两套模版与法冲突造成undefinedError
前端·javascript·vue.js
UIU1147 小时前
P1233 [ICPC 2001 Taejon R] 木棍加工
数据结构·c++·算法·动态规划
论文复现现场8 小时前
WRF、FEA 能用 L40S 加速吗?求解器检查、断点恢复与长期运行
java·数据库·算法·wrf·有限元分析·gpu计算·断点续算
ZhengEnCi8 小时前
用 AI 写代码为什么拼到最后还是拼人:算力瓶颈与领域专家提示词的本质差异
算法·架构
FRing039 小时前
JavaScript入门到精通三十二(深拷贝、浅拷贝、递归函数)
开发语言·前端·javascript
秋天的怀念_David9 小时前
第二十一夜 · 数字黑洞与西西弗斯的惩罚
java·程序人生·算法
碧海银沙音频科技研究院10 小时前
在PC电脑上用Whisper→Marian算法实现离线语音翻译功能
算法·whisper
niyongsheng10 小时前
3D 装箱算法工程化:数据结构、放置启发式与支撑规则
数据结构·算法·rust
兰亭妙微UI设计公司11 小时前
兰亭妙微ui设计公司分享:B端组件命名如何支持团队协作
前端·javascript·vue.js