Longest Palindromic Substring最长回文子串-学习动态规划Dynamic Programming(DP)

通过leetcode的查找Longest Palindromic Substring最长回文子串,来学习一下动态规划。

动态规划的核心是能把当前问题分解成已经有的更小的问题,然后直到这个问题有一个常数答案,并且这个分解过程有一个固定模式。

所以最终目的就是寻找 1. 固定的分解模式 2.常数答案。

根据回文串的定义可知,去掉回文串的首位,剩下的依然是回文串,重复这个过程,我们可以得到最终只有长度为1(奇数长度)或者0(偶数长度)的字符串,也就是一个常量解。

因此我们就得到了

  1. 固定的分解模式,及回文串去掉首尾依然是回文串,翻过来,回文串加上相同的首尾依然是回文串。
  2. 常数答案,2.1 一个字符是回文串, 2.2 两个相邻字符如果相同是回文串

假设 s为字符串,i和j表示索引,dpij=tue/false 分别表示字符串si...j是/否为回文

则 dpij=dpi+1j-1 && si==sj,及当si+1...j-1是回文且si=sj时,那么si...j也是回文,及dpij=true;

因此可以得到转换方程

java 复制代码
if (s.charAt(i) == s.charAt(j)) {
      if (j - i <= 2) { //j=i||j=i+1
         dp[i][j] = true;
      } else {
         dp[i][j] = dp[i + 1][j - 1];
      }
} else {
      dp[i][j] = false;
}

实践中有两种写法,一种是从尾向前计算,好处是当在 (i,j) 时,(i+1,j-1) 一定已经被计算,另外一种是从头向后计算,好处是比较直观。

从尾向前:

java 复制代码
public String longestPalindrome(String s) {
        int n = s.length();
        if (n < 2) {
            return s;
        }
        int maxLen = 0;
        int maxIndex = 0;
        boolean[][] dp = new boolean[n][n];

        for (int i = n - 1; i >= 0; i--) {
            for (int j = i; j < n; j++) {
                if (s.charAt(i) == s.charAt(j)) {
                    if (j - i <= 2) {
                        dp[i][j] = true;
                    } else {
                        dp[i][j] = dp[i + 1][j - 1];
                    }
                    if (dp[i][j] && (j - i + 1 > maxLen)) {
                        maxLen = j - i + 1;
                        maxIndex = i;
                    }
                } else {
                    dp[i][j] = false;
                }
            }
        }
        return s.substring(maxIndex, maxIndex + maxLen);
    }

从头向后

java 复制代码
public String longestPalindrome(String s) {
        int n = s.length();
        if (n < 2) {
            return s;
        }
        int maxLen = 0;
        int maxIndex = 0;
        boolean[][] dp = new boolean[n][n];

        for (int len = 1; len <= n; len++) {
            for (int i = 0; i + len - 1 < n; i++) {
                int j = i + len - 1;
                if (s.charAt(i) == s.charAt(j)) {
                    if (j - i <= 2) {
                        dp[i][j] = true;
                    } else {
                        dp[i][j] = dp[i + 1][j - 1];
                    }
                    if (dp[i][j] && (j - i + 1 > maxLen)) {
                        maxLen = j - i + 1;
                        maxIndex = i;
                    }
                } else {
                    dp[i][j] = false;
                }
            }
        }
        return s.substring(maxIndex, maxIndex + maxLen);
    }
相关推荐
DisonTangor16 分钟前
【腾讯混元雪耻归来】 Hy4 preview:770B 参数 MoE 旗舰模型,1M 上下文全面开源
人工智能·算法·开源·aigc·腾讯云·腾讯云ai代码助手
明月_清风1 小时前
从二叉树到 B+ 树:一文搞懂工程中「树」的演化之道
数据结构·算法·go
渡我白衣2 小时前
并查集:基础认识与模拟实现
android·java·javascript·数据结构·c++·算法·并查集
hetao17338372 小时前
2026-09-01~09-04 hetao1733837 的刷题记录
c++·算法
Evand J2 小时前
【MATLAB例程,图像滤波5】 反谐波均值滑动窗口滤波(CHMF)图像降噪与质量评价,附代码下载链接
图像处理·算法·计算机视觉·matlab·均值算法·滑动窗口滤波·均值滑动
血小板要健康2 小时前
链表 阶段算法总结
java·数据结构·笔记·算法·leetcode·链表
a187927218313 小时前
【算法】回溯算法(三):三记重锤与 N 皇后——记忆化、状态设计与三层漏斗
算法·leetcode·go·剪枝·回溯·n皇后·算法讲解
HugoStudio_SWAN4 小时前
洛谷 P1420 / P1179 / B4262 最长连号、数字统计与词频统计——统计的三种面孔
c++·学习·程序人生·算法
青 春 记 忆5 小时前
LeetCode 350. 两个数组的交集 II|Python 解法详解
python·算法·leetcode
阳明山水6 小时前
销量预测2025—2026:从模型竞赛到系统融合的范式转型
人工智能·深度学习·算法·机器学习·架构