LeetCode 5:最长回文子串(Longest Palindromic Substring)—— 题解

LeetCode 5:最长回文子串(Longest Palindromic Substring)题解

🔗 题目链接

👉 https://leetcode.cn/problems/longest-palindromic-substring/

📖 题目描述

给你一个字符串 s,找出其中最长的连续回文子串。若存在多个长度相同的最长回文子串,返回任意一个即可。

示例 1:

输入:s = "babad"

输出:"bab"

解释:"aba" 同样是符合题意的答案。

示例 2:

输入:s = "cbbd"

输出:"bb"

题目约束:

  • 1 <= s.length <= 1000
  • 字符串仅由数字和英文字母组成

📌 题目核心考点

  • 经典 区间动态规划(区间DP) 题型
  • 字符串子串问题、回文判定进阶应用
  • 面试高频算法原题,重点考察DP状态定义、遍历顺序逻辑

💡 解题核心思路(DP解法)

暴力枚举所有子串再判断回文的方式时间复杂度为 O(n³),会超时。因此使用动态规划,复用已计算的子问题结果,将时间复杂度优化至 O(n²)。

一、状态定义

定义二维DP数组:

复制代码
dp[i][j] = 表示字符串区间 s[i...j] 是否为回文子串

true:是回文子串,false:不是回文子串

二、状态转移方程(核心)

回文子串的核心特性:两端字符相等,且中间包裹的子串也是回文

复制代码
if (s[i] == s[j]) {
    // 情况1:单个字符 / 两个相邻相同字符,一定是回文
    if (j - i <= 1) {
        dp[i][j] = true;
    } 
    // 情况2:区间长度大于2,依赖内部子串的结果
    else {
        dp[i][j] = dp[i + 1][j - 1];
    }
}

简单总结:首尾字符相同,且内部子串是回文,则当前区间是回文

三、关键遍历顺序(易错重点)

dp[i][j] 的状态依赖于 dp[i+1][j-1],因此遍历顺序固定:

  • i(左边界):从后往前遍历
  • j(右边界):从前往后遍历

该顺序保证:计算大区间时,内部小区间的子问题已经算完

复制代码
for (int i = len - 1; i >= 0; i--)
    for (int j = i; j < len; j++)

✅ 完整AC代码(修缮你的原代码)

java 复制代码
class Solution {
    public String longestPalindrome(String s) {
        // 初始最长长度为1,答案初始化为第一个字符(修复原代码空串BUG)
        int maxLen = 1;
        String ans = s.substring(0, 1);

        int len = s.length();
        char[] charArr = s.toCharArray();
        boolean[][] dp = new boolean[len][len];

        // 左边界倒序遍历
        for (int i = len - 1; i >= 0; i--) {
            // 右边界正序遍历
            for (int j = i; j < len; j++) {
                if (charArr[i] == charArr[j]) {
                    // 长度1、2直接回文
                    if (j - i <= 1) {
                        dp[i][j] = true;
                    } else {
                        // 长度大于2依赖内部
                        dp[i][j] = dp[i + 1][j - 1];
                    }

                    // 更新最长回文子串
                    if (dp[i][j] && (j - i + 1) > maxLen) {
                        maxLen = j - i + 1;
                        ans = s.substring(i, j + 1);
                    }
                }
            }
        }
        return ans;
    }
}

⏱️ 复杂度分析

指标 复杂度 说明
时间复杂度 O(n²) 两层循环枚举所有区间
空间复杂度 O(n²) 二维dp数组开销

💡 核心一句话总结

区间DP:首尾相等且内部子串回文 → 当前区间回文;逆序遍历左边界,保证子问题先解。

📝 面试高频追问(必背)

1. 为什么 i 必须倒序遍历?

dp[i][j] 依赖 dp[i+1][j-1],也就是当前行依赖下一行

只有 i 从后往前算,i+1 的结果才已经提前算好了。

2. 为什么要单独判断 j - i <= 1

当子串长度为 1、2 时,i+1 > j-1,没有内部子区间,不能走转移方程,需要手动初始化基准回文。

3. 可以优化空间吗?

可以。中心扩展法空间 O(1),时间同样 O(n²),是面试最优解。

需要我把中心扩展法的完整题解+代码也直接贴给你吗?

相关推荐
j7~2 小时前
【算法】专题一:双指针之移动零,复写零,快乐数
数据结构·c++·算法·双指针·快乐数·移动零·复写零
lqqjuly2 小时前
KAN 网络深度解析
算法
阿里matlab建模师2 小时前
【机场停机位分配】matlab实现基于遗传算法的机场停机位分配优化研究
开发语言·算法·数学建模·matlab·全国大学生数学建模竞赛
小雨下雨的雨7 小时前
井字棋AI机器人实现详解 - Minimax算法实战-鸿蒙PC Electron框架完成
前端·人工智能·算法·华为·electron·鸿蒙
xieliyu.10 小时前
Java算法精讲:双指针(三)
java·开发语言·算法
一条小锦吕*10 小时前
基于Spring Boot + 数据可视化 + 协同过滤算法的推荐系统设计与实现(源码+论文+部署全讲解)
spring boot·算法·信息可视化
如竟没有火炬12 小时前
最大矩阵——单调栈
数据结构·python·线性代数·算法·leetcode·矩阵
8Qi812 小时前
LeetCode 1143 & 718:最长公共子序列 / 最长重复子数组
算法·leetcode·职场和发展·动态规划
绿算技术13 小时前
万卡推理集群存储选型分析:从核心架构到应用视角
大数据·科技·算法·架构