两道字符串经典题复盘:最长回文子串 & 最长公共子序列

今天复盘两道面试高频的字符串动态规划题:「最长回文子串」「最长公共子序列」。一道是字符串回文问题的基础,另一道是双字符串 DP 的经典模板,两者都是字符串处理的核心考点。


一、5. 最长回文子串(中等)

题目描述

给你一个字符串 s,找到 s 中最长的回文子串。

核心思路 1:中心扩展法(直观高效)

回文的本质是对称,所以我们可以把每个字符(奇数长度)和每对相邻字符(偶数长度)当作中心,向两边扩展,找到以该中心为对称轴的最长回文子串。

  • 对于每个中心 i
    • 奇数长度:以 (i, i) 为中心扩展
    • 偶数长度:以 (i, i+1) 为中心扩展
  • 每次扩展时,只要左右字符相等就继续,直到不相等为止,记录当前最长的子串。

完整代码(Java)

java

运行

复制代码
class Solution {
    public String longestPalindrome(String s) {
        if (s == null || s.length() < 1) return "";
        int start = 0, end = 0;
        for (int i = 0; i < s.length(); i++) {
            int len1 = expandAroundCenter(s, i, i);
            int len2 = expandAroundCenter(s, i, i + 1);
            int len = Math.max(len1, len2);
            if (len > end - start) {
                start = i - (len - 1) / 2;
                end = i + len / 2;
            }
        }
        return s.substring(start, end + 1);
    }

    private int expandAroundCenter(String s, int left, int right) {
        while (left >= 0 && right < s.length() && s.charAt(left) == s.charAt(right)) {
            left--;
            right++;
        }
        return right - left - 1;
    }
}

核心思路 2:动态规划

定义 dp[i][j] 表示字符串 s[i..j] 是否为回文子串:

  • 状态转移:dp[i][j] = (s[i] == s[j]) && dp[i+1][j-1]
  • 边界条件:
    • 单个字符:dp[i][i] = true
    • 两个字符:dp[i][i+1] = (s[i] == s[i+1])
  • 遍历方式:按子串长度从小到大遍历,避免依赖未计算的状态。

时间与空间复杂度

  • 中心扩展法:时间 O (n²),空间 O (1)
  • 动态规划:时间 O (n²),空间 O (n²)(可优化为一维)

二、1143. 最长公共子序列(中等)

题目描述

给定两个字符串 text1text2,返回这两个字符串的最长公共子序列的长度。如果不存在公共子序列,返回 0

核心思路:二维动态规划

这是双字符串 DP 的经典模板题,核心是定义状态并利用 "选或不选" 的思想转移:

  • 定义 dp[i][j] 表示 text1[0..i-1]text2[0..j-1] 的最长公共子序列长度。
  • 状态转移:
    • 如果 text1[i-1] == text2[j-1]dp[i][j] = dp[i-1][j-1] + 1(当前字符匹配,长度 + 1)
    • 如果不相等:dp[i][j] = Math.max(dp[i-1][j], dp[i][j-1])(选其中一个字符串的前一个状态)
  • 边界条件:dp[0][j] = 0dp[i][0] = 0(空字符串的公共子序列长度为 0)

完整代码(Java)

java

运行

复制代码
class Solution {
    public int longestCommonSubsequence(String text1, String text2) {
        int m = text1.length();
        int n = text2.length();
        int[][] dp = new int[m + 1][n + 1];
        for (int i = 1; i <= m; i++) {
            for (int j = 1; j <= n; j++) {
                if (text1.charAt(i - 1) == text2.charAt(j - 1)) {
                    dp[i][j] = dp[i - 1][j - 1] + 1;
                } else {
                    dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);
                }
            }
        }
        return dp[m][n];
    }
}

优化:一维 DP

因为每次更新 dp[i][j] 只需要上一行的 dp[i-1][j] 和当前行的 dp[i][j-1],可以将二维数组压缩为一维,空间复杂度从 O (mn) 降到 O (min (m,n)):

java

运行

复制代码
class Solution {
    public int longestCommonSubsequence(String text1, String text2) {
        if (text1.length() < text2.length()) {
            return longestCommonSubsequence(text2, text1);
        }
        int m = text1.length();
        int n = text2.length();
        int[] dp = new int[n + 1];
        for (int i = 1; i <= m; i++) {
            int prev = 0;
            for (int j = 1; j <= n; j++) {
                int temp = dp[j];
                if (text1.charAt(i - 1) == text2.charAt(j - 1)) {
                    dp[j] = prev + 1;
                } else {
                    dp[j] = Math.max(dp[j], dp[j - 1]);
                }
                prev = temp;
            }
        }
        return dp[n];
    }
}

两道题对比总结

表格

题目 类型 核心思想 时间复杂度 空间复杂度 关键考点
最长回文子串 字符串回文 / DP 中心扩展 / DP 状态转移 O(n²) O (1)(中心扩展) 回文对称性、子串与子序列的区别
最长公共子序列 双字符串 DP 选或不选的状态转移 O(mn) O (min (m,n))(优
相关推荐
许彰午10 小时前
36_Java设计模式之代理模式
java·设计模式·代理模式
devilnumber4 天前
静态代理 & 动态代理:实战运用 + 场景区别 + 怎么选
java·开发语言·代理模式
devilnumber4 天前
想真正吃透 + 灵活运用 Java 代理模式
java·开发语言·代理模式
故渊at10 天前
系列一:架构思想进阶 | 第3篇 SOLID 原则与设计模式实战:从“代码搬运工”到“架构师”的必经之路
观察者模式·设计模式·重构·架构·代理模式
basketball61611 天前
设计模式入门:5. 代理模式详解 C++实现
c++·设计模式·代理模式
2601_9611940211 天前
2026初级会计经济法基础知识点汇总
python·django·pdf·virtualenv·代理模式·pygame
2601_9611940211 天前
考研模拟卷谁的比较好|27李林合工大肖四肖八数学英语408PDF
考研·elasticsearch·全文检索·代理模式·lucene·桥接模式·访问者模式
Rick199313 天前
代理模式 vs 适配器模式
代理模式·适配器模式
老码观察15 天前
设计模式实战解读(八):代理模式——控制访问的隐形中间层
设计模式·代理模式
青山师16 天前
动态规划算法深度解析:从状态转移方程到工业级优化
数据结构·算法·面试·动态规划·代理模式·java面试