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²),是面试最优解。

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

相关推荐
GuWenyue1 小时前
传统Agent工具两大痛点!300行代码落地MCP跨语言工具,彻底解耦LLM与工具
前端·人工智能·算法
我叫洋洋2 小时前
C ++ [ hello world ]
c语言·c++·算法
奋发向前wcx3 小时前
y1,y2总复习笔记5 2026.7.19
数据结构·笔记·算法
战族狼魂7 小时前
高频面试题精选:分治与AI Agent架构
人工智能·算法·大模型·大语言模型
李剑一7 小时前
你用过网易的将军令嘛?它底层实现账号保护的原理相当简单粗暴
算法
Scott9999HH7 小时前
告别流量波动玄学!从法拉第电磁定律到底层 C/C++ 流量累积算法,深度解密工业级电磁流量计选型与开发
c语言·c++·算法
中达瑞和-高光谱·多光谱7 小时前
1nm到8nm光谱分辨率,你的应用该选哪款光谱相机?
算法·高光谱·高光谱相机
香辣牛肉饭8 小时前
【算法】动态规划 最长公共子序列(LCS)
经验分享·笔记·算法·动态规划
旖-旎9 小时前
LeetCode 279:完全平方数(完全背包)—— 题解
c++·算法·leetcode·动态规划·背包问题