LintCode刷题——最长的回文序列(区间DP)
题目描述
描述
给一字符串 s, 找出在 s 中的最长回文子序列的长度. 你可以假设 s 的最大长度为 1000
.
样例
样例1
输入: "bbbab"
输出: 4
解释:
一个可能的最长回文序列为 "bbbb"
样例2
输入: "bbbbb"
输出: 5
标签
优步 亚马逊 动态规划 区间型动态规划
分析
区间DP,与序列型动态规划的思考方式不同,区间DP每次都以区间进行讨论,但也是从小区间到大区间的这种顺序进行,这一点还是和任意类型的动态规划相符,因为动态规划算法的核心思想就是想一步步通过求解子问题的解进而递推出原问题的解的过程,所以仍然要先计算小区间,再计算大区间。
这里我们要注意的点:对长度为0的区间和长度为1的区间要特殊处理一下,不然后面就会有些许麻烦或不必要的问题
AC代码
1 public class Solution { 2 /** 3 * @param s: the maximum length of s is 1000 4 * @return: the longest palindromic subsequence's length 5 */ 6 public int longestPalindromeSubseq(String s) { 7 // write your code here 8 if (s == null || s.length() == 0) { 9 return 0; 10 } 11 char[] c = s.toCharArray(); 12 int n = c.length; 13 14 // 定义状态:f[i][j] 表示区间(i,j)的最长回文子序列长度 15 // 区间型动态规划,不用开n + 1 16 int[][] f = new int[n][n]; 17 18 /* 19 区间型动态规划的注意点:要从考虑区间开始,而且是从小区间到大区间 20 */ 21 // 初始化 22 // 特殊处理区间0,即本身 23 for (int i = 0; i < n; i++) { 24 f[i][i] = 1; 25 } 26 27 // 特殊处理区间1 28 for (int i = 0; i < n - 1; i++) { 29 if (c[i] == c[i + 1]) { 30 f[i][i + 1] = 2; 31 } else { 32 f[i][i + 1] = 1; 33 } 34 } 35 36 // 转移方程 37 // 分区间,从区间为2开始,注意:区间最大为n - 1 38 for (int len = 2; len < n; len++) { 39 // 定住左边界 40 for (int i = 0; i + len <= n - 1; i++) { 41 // 右边界 42 int j = i + len; 43 if (c[i] == c[j]) { 44 // 这里很容易犯错误,是+2,而不是像最长公共子序列一样+1 45 f[i][j] = f[i + 1][j - 1] + 2; 46 } else { 47 f[i][j] = Math.max(f[i + 1][j], f[i][j - 1]); 48 } 49 } 50 } 51 52 // 返回结果 53 return f[0][n - 1]; 54 } 55 }
LintCode链接:https://www.lintcode.com/problem/667/
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)