news 2026/11/5 1:55:12

DeepSeek LeetCode 516. 最长回文子序列 Java实现

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
DeepSeek LeetCode 516. 最长回文子序列 Java实现

LeetCode 516. 最长回文子序列 · Java 实现

题意

给定字符串 s,求其最长回文子序列的长度。

注意区分"子序列"和"子串":

· 子序列不要求连续,可以跳跃(如 bbbab 的最长回文子序列是 bbbb,长度 4)
· 子串必须连续(那是另一道题 647/5)

示例:

s = "bbbab" → 4 (bbbb) s = "cbbd" → 2 (bb)

思路一:区间 DP(标准解法,推荐)

状态定义:

dp[i][j] = 区间 s[i…j] 内的最长回文子序列长度

转移方程:

情况 转移
s[i] == s[j] dp[i][j] = dp[i+1][j-1] + 2
s[i] != s[j] dp[i][j] = max(dp[i+1][j], dp[i][j-1])

初始化: dp[i][i] = 1(单个字符本身就是长度 1 的回文)

遍历顺序的关键:dp[i][j] 依赖 dp[i+1][j-1]、dp[i+1][j]、dp[i][j-1],即依赖更长区间(i 更大、j 更小)。
所以必须:i 从 n-1 倒序,j 从 i+1 正序。

classSolution{publicintlongestPalindromeSubseq(Strings){intn=s.length();int[][]dp=newint[n][n];// 单字符天然是长度 1 的回文for(inti=0;i<n;i++)dp[i][i]=1;for(inti=n-1;i>=0;i--){for(intj=i+1;j<n;j++){if(s.charAt(i)==s.charAt(j)){dp[i][j]=dp[i+1][j-1]+2;}else{dp[i][j]=Math.max(dp[i+1][j],dp[i][j-1]);}}}returnn==0?0:dp[0][n-1];}}

复杂度: 时间 O(n²),空间 O(n²)


思路二:滚动数组空间优化(一维 DP)

观察转移:dp[i][j] 只依赖下一行 dp[i+1][*] 和本行左侧 dp[i][j-1],可以用一维数组 + 一个变量保存"上一轮的值"来压缩。

classSolution{publicintlongestPalindromeSubseq(Strings){intn=s.length();if(n==0)return0;int[]dp=newint[n];java.util.Arrays.fill(dp,1);// dp[j] 初始表示 dp[j][j] = 1for(inti=n-1;i>=0;i--){intpre=0;// 表示 dp[i+1][j-1],当 j = i+1 时为 dp[i+1][i] = 0for(intj=i+1;j<n;j++){inttemp=dp[j];// 暂存 dp[i+1][j]if(s.charAt(i)==s.charAt(j)){dp[j]=pre+2;// dp[i+1][j-1] + 2}else{dp[j]=Math.max(dp[j],dp[j-1]);// dp[j] = dp[i+1][j](尚未更新)// dp[j - 1] = dp[i][j-1](本轮已更新)}pre=temp;// 为下一个 j 准备 dp[i+1][j-1]}}returndp[n-1];}}

复杂度: 时间 O(n²),空间 O(n)

⚠️ pre 的更新时机是易错点:必须先 temp = dp[j] 把"旧值"(即 dp[i+1][j])存下来,等 dp[j] 用完后,再把 pre = temp 供下一列 j+1 用作 dp[i+1][(j+1)-1] = dp[i+1][j]。顺序反了就错。


思路三:转化为 LCS

一个回文串的"前一半"必然等于"后一半的反转",所以:

s 的最长回文子序列 = s 与 reverse(s) 的最长公共子序列(LCS)长度。

classSolution{publicintlongestPalindromeSubseq(Strings){Stringt=newStringBuilder(s).reverse().toString();intn=s.length();int[]dp=newint[n+1];for(inti=1;i<=n;i++){intpre=0;for(intj=1;j<=n;j++){inttemp=dp[j];if(s.charAt(i-1)==t.charAt(j-1)){dp[j]=pre+1;}else{dp[j]=Math.max(dp[j],dp[j-1]);}pre=temp;}}returndp[n];}}

· 思路直观,但常数略大(多构造一个 reverse 串)。
· 面试中作为"第二种角度"可以提,主推思路一。


三种方法对比

方法 时间 空间 推荐度
区间 DP(二维) O(n²) O(n²) ⭐⭐⭐⭐⭐ 面试首选,逻辑最清晰
区间 DP(一维滚动) O(n²) O(n) ⭐⭐⭐⭐ 空间优化加分
转 LCS O(n²) O(n) ⭐⭐⭐ 思路巧妙但略绕


关键坑点 ⚠️

  1. 子序列 vs 子串混淆
    · 本题是子序列(可跳),别写成中心扩展或区间子串判定。
    · 典型反例:“bbbab” 的结果是 4(bbbb),若是子串答案会不同。
  2. 遍历顺序写反
    · dp[i][j] 依赖 dp[i+1][*] 和 dp[i][j-1],所以 i 必须倒序、j 必须正序。
    · 如果 i 正序,dp[i+1][…] 还没算出来,全是 0。
  3. s[i] == s[j] 时要加 2,不是 1
    · 首尾两字符都加进来。
  4. j 从 i+1 开始,不是 i
    · dp[i][i] = 1 已经初始化,j == i 不应该进循环(否则会把 dp[i][i] 覆盖)。
  5. i+1 > j-1 的边界
    · 当 j == i+1 时,dp[i+1][j-1] = dp[i+1][i],长度为 0 的区间。二维数组里它是 0(未初始化),正好正确;一维滚动版里要用 pre = 0 来模拟。
    · 如果初始化为 1 会导致 “aa” 这种输入被算成 3。
  6. 空串和单字符
    · n == 0 返回 0;n == 1 返回 1(因为 dp[0][0] 已初始化为 1,且内层循环不执行,直接返回 dp[0][0] = 1)。
  7. 空间优化时 pre 更新时机
    · 见思路二代码注释:先用旧值,再更新 pre。顺序反了会把"本行刚算出的值"误当"上一行的值"。

一句话总结

区间 DP:dp[i][j] 表示 s[i…j] 的最长回文子序列长度。首尾相等 +2,不等取 max,i 倒序 j 正序遍历。O(n²) 时间,O(n) 空间可用滚动数组优化。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/11/5 1:55:10

【共创稿事节】HarmonyOS 7.0 Navigation路由表:从接入到生产验证

Navigation 是鸿蒙官方点名的路由方案,可健康菜谱助手接入它时,官方示例没有回答的问题比给的多:路由表里塞几十个页面怎么管理、跨模块注册路由表怎么避免冲突、NavDestination 的生命周期和页面栈怎么配合、动态路由(参数决定目标页)怎么落地。这篇复盘 Navigation 路由表从接…

作者头像 李华
网站建设 2026/11/5 1:55:08

从反向传播到 AlexNet:1986 到 2012,中间那二十六年发生了什么

&#x1f44b; Hi&#xff0c;我擅长 AI 大模型应用落地、意识解码与 AI 开发工具链 。 &#x1f4a1; 创业路上&#xff0c;用技术换时间&#xff0c;一起把 AI 变成生产力 &#x1f680; >从反向传播到 AlexNet&#xff1a;1986 到 2012&#xff0c;中间那二十六年发生了什…

作者头像 李华
网站建设 2026/11/5 1:55:08

毕设/课设别再熬夜画图了!SpringBoot个性化在线课程推荐:功能结构图、流程图、数据流图、UML类图、时序图、用例图、三线表、用例表、开题报告,用捷码AI一键生成

个性化在线课程推荐-综合设计成果/ ├── 00-交付清单/ manifest.json README ├── 01-系统图表/ 8 类系统图&#xff08;E-R / 功能结构 / 数据流 / 架构 / 流程 / 类图 / 时序 / 用例&#xff09; ├── 02-设计资料/ 数据库脚本 └── 03-交付成…

作者头像 李华
网站建设 2026/11/5 1:55:06

人类经济究极论(Ultimate Human Economics)

人类经济究极论&#xff08;Ultimate Human Economics&#xff09; 一、 核心概念&#xff1a;宏观“化债”与系统跃迁 随着认知架构的升级与科技的指数级升级&#xff0c;人类正在超越传统分配模型的局限。过去一切因分配弊端、信息不对称、物理阻隔而产生的消耗行为&#xff…

作者头像 李华
网站建设 2026/11/5 1:55:00

微信小程序练习:video 组件

一、案例描述 设计一个小程序&#xff0c;演示 video 组件的功能和使用方法&#xff0c;以及发送弹幕和创建随机颜色的方法。小程序运行后可以播放视频&#xff0c;在指定时间显示预置弹幕&#xff0c;还可以通过输入框和按钮发送随机颜色的弹幕。 二、实现思路 页面中使用 vid…

作者头像 李华
网站建设 2026/11/5 1:53:44

低代码和AI Coding怎么选?做企业应用,当然是全都要

低代码和AI Coding怎么选&#xff1f;做企业应用&#xff0c;当然是全都要一个报销应用&#xff0c;第一版要多久&#xff1f; 拖几个输入框&#xff0c;加上金额、附件&#xff0c;再接两级审批&#xff0c;页面已经很像样。换成AI Coding&#xff0c;把需求交给编程工具&…

作者头像 李华