LeetCode 516:最长回文子序列

LeetCode 516:最长回文子序列

🔗 题目链接

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

📖 题目概要

给你一个字符串 s ,找出其中最长的回文子序列,并返回该序列的长度。

子序列 定义:不要求字符连续,在不改变原有字符顺序的前提下,可以删除某些字符(也可以不删除)得到新字符串。

回文定义:正读和反读完全一致的字符串。

示例

示例 1:

输入:s = "bbbab"

输出:4

解释:一个可能的最长回文子序列为 "bbbb"。

示例 2:

输入:s = "cbbd"

输出:2

解释:一个可能的最长回文子序列为 "bb"。

约束条件

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

📌 题目考点

  • 经典区间动态规划
  • 回文子序列 DP 模型(与最长回文子串区分)
  • 区间 DP 遍历顺序、状态转移逻辑考察
  • 字符串动态规划高频面试题

💡 解题思路

本题和「最长回文子串」不同:子序列不要求连续,因此解题思路采用标准区间 DP 求解。

1. 状态定义

定义二维 dp 数组:

dp[i][j] 表示字符串区间 s[i ... j] 中,最长回文子序列的长度

2. 初始状态

单个字符一定是回文子序列,长度为 1。

因此初始化:dp[i][i] = 1(所有对角线位置赋值为 1)。

3. 状态转移方程

分两种情况讨论区间 [i, j]

  1. 两端字符相等(s[i] == s[j]

    两端字符可以同时加入回文序列,结果为内部区间最长回文长度 + 2

    dpij=dpi+1j−1+2dpij = dpi+1j-1 + 2dpij=dpi+1j−1+2

  2. 两端字符不相等(s[i] != s[j]

    只能舍弃左端字符 或 舍弃右端字符,取两种情况的最大值:

    dpij=max⁡(dpi+1j,dpij−1)dpij = \max(dpi+1j, dpij-1)dpij=max(dpi+1j,dpij−1)

4. 遍历顺序(核心要点)

dp[i][j] 的结果依赖于:dp[i+1][j-1]dp[i+1][j]dp[i][j-1],也就是当前区间依赖更小的内层区间 / 下一行 / 前一列

因此遍历规则:

  • 左边界 i从后往前遍历(从字符串末尾向开头)
  • 右边界 j从 i+1 开始向后遍历(保证区间长度由小到大)

5. 最终答案

整个字符串对应区间 [0, len-1],最终返回 dp[0][len-1]

✅ AC 代码

java 复制代码
class Solution {
    public int longestPalindromeSubseq(String s) {
        char[] ss = s.toCharArray();
        int len = s.length();
        int [][] dp = new int[len+1][len+1];
        
        // 初始化:单个字符最长回文子序列长度为 1
        for(int i = 0; i < len; i++) {
            dp[i][i] = 1;
        }

        // 左边界从后往前遍历
        for(int i = len - 1; i >= 0; i--) {
            // 右边界从 i+1 开始
            for(int j = i + 1; j < len; j++) {
                if(ss[i] == ss[j]) {
                    // 两端字符相等,内部结果 + 2
                    dp[i][j] = dp[i+1][j-1] + 2;
                } else {
                    // 两端不等,取左右区间最大值
                    dp[i][j] = Math.max(dp[i+1][j], dp[i][j-1]);
                }
            }
        }
        return dp[0][len-1];
    }
}

⏱️ 复杂度分析

指标 复杂度 说明
时间复杂度 O(n2)O(n^2)O(n2) 两层循环遍历所有区间,nnn 为字符串长度
空间复杂度 O(n2)O(n^2)O(n2) 开辟二维 dp 数组存储区间状态

💡 补充总结

  1. 区分易混点:最长回文子串(连续)、最长回文子序列(不连续),二者均常用区间 DP,但状态转移逻辑不同。
  2. 遍历顺序:区间 DP 通用规律,依赖内层子区间时,左边界逆序遍历。
  3. 基础边界:单个字符回文长度固定为 1,是 DP 初始化的关键。
相关推荐
youngerwang2 小时前
【从搬运工到协处理器:网卡芯片架构、算法、验证与边缘演进深度剖析】
网络·算法·架构·芯片
KaMeidebaby3 小时前
卡梅德生物技术快报|纯化重组蛋白实操详解
人工智能·python·tcp/ip·算法·机器学习
手写码匠3 小时前
从零实现 Prompt 工程引擎:结构化提示、自动优化与多轮自省体系
人工智能·深度学习·算法·aigc
无限码力4 小时前
阿里算法岗 0530笔试真题 - 多约束条件下的元素匹配统计
算法·阿里笔试真题·阿里机试真题·阿里算法岗笔试
lqqjuly4 小时前
MLA — 多头潜在注意力深度解析
深度学习·神经网络·算法
吴可可1234 小时前
SolidWorks草图转三维DWG技巧
算法
redaijufeng5 小时前
C++雾中风景7:闭包
c++·算法·风景
小欣加油5 小时前
leetcode287寻找重复数
数据结构·c++·算法·leetcode