java最长回文子序列_LeetCode[5] - 最长回文子串动态规划
题目
给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为1000。
示例 1:
输入: "babad"
输出: "bab"
注意: "aba"也是一个有效答案。
示例 2:
输入: "cbbd"
输出: "bb"
tips: 回文字符串:正读反读都一样
叙事
这道题目level为中等,读第一遍我就觉得可能会很棘手,当然立刻就有一个简单的解题思路,因为知道这种解法很烂所以一直没有coding。直到有一天····
强迫症
强迫症患者根本无法继续愉快coding了。。。只好不拖延,解决这个棘手的问题····当然肯定是因为自己菜才觉得棘手···
分析
最简单能想到的解决方案就是把字符串的所有子串枚举出来,每一个都判断是否是回文字符串,然后选长度最长的回文子串。。。后来我才知道这个算法叫暴力算法···名字很酷···暴力足以解决很多问题····代码很简单
public String longestPalindrome(String s) {
if(s.isEmpty()){
return s;
}
String res=s.substring(0,1);
for (int i = 0; i < s.length(); i++) {
for (int j = i + 1; j <= s.length(); j++) {
String k=s.substring(i,j);
String rk=new StringBuffer(k).reverse().toString();
if(k.equals(rk)&&k.length()>res.length()){
res=k;
}
}
}
return res;
}
一段不加注释都能看得懂的代码···我们执行了一下····
完美gg
果然···暴力的leetcode都看不过去···
现有的知识和智慧已经不够用了。然后去google解法。最强的是一个叫马拉车的算法,看起来有点复杂,而且对其他算法题帮助不大,所以拖拉的楼主决定晚点再学这个马拉车。接下来就是动态规划算法。。。等我起一个title。
动态规划
为什么单独将动态规划罗列出来呢,因为这在算法问题中好像十分普遍和重要。楼主之前刷面试题,很多算法问题的answer 作者都直接甩一句动态规划···好,今天就直面曾经欠下的债。动态规划颇有点“大事化小,小事化了”的感觉。在动态规划中有三个重要的元素最优子结构,边界,状态转移公式,我们稍后结合一个例子理解一下这仨概念~
理解动态规划有一个最典型的例子:
有面值分别为1,3,5的三种硬币若干,需要凑成11元最少需要多少硬币,凑成n元最少需要多少硬币?
和往常一样我们来一起找规律:
假如:
凑成0元需要0个硬币 //d(0)=0
凑成1元需要1个1元硬币 //d(1)=d(0)+1
凑成2元需要2个1元硬币 //d(2)=d(1)+1
凑成3元需要3个1元硬币或者1个3元硬币,那么我们选择1个3元硬币 //d(3)=min{d(2)+1,d(3-3)+1}
凑成4元需要1个3元硬币,1个1元硬币 //d(4)=d(3)+1;
凑成5元需要1个3元硬币,2个1元硬币或者1个5元硬币,那么我们选择1个5元硬币 //d(5)=min{d(4)+1,d(5-5)+1}
。。。。
抽离出来d(i)=min{ d(i-1)+1,d(i-vj)+1 },其中i-vj >=0,vj表示第j个硬币的面值;
这里d(i-1)+1和d(i-vj)+1是d(i)的最优子结构,d(0)=0是边界,d(i)=min{ d(i-1)+1,d(i-vj)+1 }是状态转移公式。其实我们根据边界+状态转移公式就能得到最终动态规划的结果。
上述程序的java实现
public int dp(int n) {
n++;
int min[] = new int[n];
int[] V = {1, 3, 5};
min[0]=0;
for (int i = 1; i < n; i++) {
min[i] = min[i-1]+1;
for (int j = 0; j < V.length; j++) {
if (V[j] > i) {
break;
}
if (min[i - V[j]] < min[i-1]) {
min[i] = min[i - V[j]] + 1;
}
}
}
return min[n - 1];
}
因为我也是今天才去了解动态规划,所以有可能有些理解不对表述不对的地方。欢迎指出。
关于动态规划我看了的两篇文章:
动态规划:从新手到专家
参考:程序员小灰动态规划
动态规划解决最长回文子串
我们创建一个二维数组,boolean[][]dp,其中dp[i][j]表示字符串第i到j是否为回文。那么边界值其实很清楚了,j-i=1的都为true 字符串长度为1的都为true。状态转换如何设定呢?当字符串i所在的字符等于字符串j所在的字符,并且它的内部(dp[i+1][j-1])为回文那么dp[i][j]为true。因为这样的规律,我们要保证判断dp[i][j]的时候dp[i+1][j-1]已经判断,所以我们遍历采用i降序j升序的嵌套遍历的方式
public String longestPalindrome(String s) {
if (s.isEmpty()) {
return s;
}
int n = s.length();
boolean[][] dp = new boolean[n][n];
int left = 0;
int right = 0;
for (int i = n - 2; i >= 0; i--) {
dp[i][i] = true;
for (int j = i + 1; j < n; j++) {
dp[i][j] = s.charAt(i) == s.charAt(j) &&( j-i<3||dp[i+1][j-1]);//小于3是因为aba一定是回文
if(dp[i][j]&&right-left
left=i;
right=j;
}
}
}
return s.substring(left,right+1);
}
这次我们再运行,发现顺利通过leetcode的考验~~
测试用例:dsfsdhadhfkdsdsfsdhadhdsfsdhadhfkddsfsdhadhfkdsahfksadhdsfsdhadhfkdsahfksadhfksddsfsdhadhfkdsahfksadhfksdhfusdihfksjadfhksadjkdsahfdsjkhfksdhffhiawoeuruihweiyrtiuoncsdbfzmbfkhfioaewncfhskdsfsdhadhfkdsahfksadhfksdhfusdihfksjadfhksadjkdsahfdsjkhfksdhffhiawoeuruihweiyrtiuoncsdbfzmbfkhfioaewncfhskhfusdihfksjadfhksadjkdsahfdsjkhfksdhffhiawoeuruihweiyrtiuoncsdbfzmbfkhfioaewncfhskdsfsdhadhfkdsahfksadhfksdhfusdihfksjadfhksadjkdsahfdsjkhfksdhffhiawoeuruihweiyrtiuoncsdbfzmbfkhfioaewncfhskdsfsdhadhfkdsahfksadhfksdhfusdihfksjadfhksadjkdsahfdsjkhfksdhffhiawoeuruihweiyrtiuoncsdbfzmbfkhfioaewncfhskdsfsdhadhfkdsahfksadhfksdhfusdihfksjadsfsdhadhfkdsahfksadhfksdhfusdihfksjadfhksadjkdsahfdsjkhfksdhffhiawoeuruihweiyrtiuoncsdbfzmbfkhfioaewncfhskdsfsdhadhfkdsahfksadhfksdhfusdihfksjadfhksadjkdsahfdsjkhfksdhffhiawoeuruihweiyrtiuoncsdbfzmbfkhfioaewncfhskdfhksadjkdsahfdsjkhfksdhffhiawoeuruihweiyrtiuoncsdbfzmbfkhfioaewncfhskfdsfsdhadhfkdsahfksadhfksdhfusdihfksjadfhksadjkdsahfdsjkhfksdhffhiawoeuruihweiyrtiuoncsdbfzmbfkhfioaewncfhskksdhfusdihfksjadfhksadjkdsahfdsjkhfksdhffhiawoeuruihweiyrtiuoncsdbfzmbfkhfioaewncfhsksahfksadhfksdhfusdihfksjadfhksadjkdsahfdsjkhfksdhffhiawoeuruihweiyrtiuoncsdbfzmbfkhfioaewncfhskfkdsahfksadhfksdhfusdihfksjadfhksadjkdsahfdsjkhfksdhffhiawoeuruihweiyrtiuoncsdbfzmbfkhfioaewncfhskahfksadhfksdhfusdihfksjadfhksadjkdsahfdsjkhfksdhffhiawoeuruihweiyrtiuoncsdbfzmbfkhfioaewncfhsk
结果
哈哈好不好奇特别暴力算法呀哈哈哈哈哈~~~时间复杂度和空间复杂度达到极致的算法!!
希望大家能教教我马拉车算法!!
java最长回文子序列_LeetCode[5] - 最长回文子串动态规划相关推荐
- 【1错笔记】psd面试——最长回文子序列 动态规划(2000字超详细解题)
题目: 链接:https://ac.nowcoder.com/acm/contest/90/D 来源:牛客网 题目描述 掌握未来命运的女神 psd 师兄在拿了朝田诗乃的 buff 后决定去实习. 埃森 ...
- LeetCode.516 最长回文子序列 详解
题目详情 给定一个字符串s,找到其中最长的回文子序列.可以假设s的最大长度为1000. 示例 1: 输入: "bbbab" 输出: 4 一个可能的最长回文子序列为 "bb ...
- 拦截导弹 最长上升/下降子序列
题意, 长度为n的序列, a1,a2, ...,ai, ..., an, 求最长严格上升子序列长度,与最长下降非严格自序列长度. 解法: 首先不得不吐嘈下题目的读入,恶心指数上达5颗星. 对 ...
- 最长公共上升子序列(LCIS)
题意: 求最长公共上升子序列 题解: 最长公共上升子序列 = 最长公共子序列(LCS)与最长上升子序列(LIS) LCS核心代码: for(int i=1;i<=n;i++){for(int j ...
- lintcode 最长上升连续子序列 II(二维最长上升连续序列)
题目链接:http://www.lintcode.com/zh-cn/problem/longest-increasing-continuous-subsequence-ii/ 最长上升连续子序列 I ...
- 动态规划之最长不下降子序列
一.概念明确 先来看一串数字:(20,17,19,22,4,7,10,12,5,2,13) 1.序列:像以上排成一列的数字,我们叫它序列,其中每个数字,可以被称为一个元素. 2.子序列:将序列中的部分 ...
- 最长上升子序列、最长公共子序列、最长公共上升子序列(LIS、LCS、LCIS)
LIS.LCS.LCIS 最长上升子序列LIS 最长公共子序列LCS 最长公共上升子序列LCIS 最长上升子序列LIS 题目链接:AcWing895. 最长上升子序列 这里只说明 O ( n 2 ) ...
- JAVA:实现LongestPalindromicSubsequence最长回文子序列算法(附完整源码)
JAVA:实现LongestPalindromicSubsequence最长回文子序列算法 package com.thealgorithms.dynamicprogramming; public c ...
- java最长回文子序列_在一个字符串里面怎么找出最长回文子序列长度
回文字符串是什么?类似于level,noon,abbba这种,就是从左读和从右读都是同一个字符串.... 先说一下我的思路: 比如现在有字符串:"12212321" 1,先在每个字 ...
最新文章
- 干货 | 20个教程,掌握时间序列的特征分析(附代码)
- 学长毕业日记 :本科毕业论文写成博士论文的神操作20170318
- Android Butterknife 8.4.0 使用方法总结
- Thinkpad上安装Ubuntu相关事项
- Seeed Raspberry Pi广角摄像/相机模块 支持Pi所有版本 OV5647
- Invalid bound statement (not found):出现的原因和解决方法
- 官方暗示与TÜV莱茵合作? MIUI12真的不远了
- Stack Overflow 遭黑客入侵;中国首条 5G 覆盖地铁诞生;VS Code 1.34 发布!| 极客头条...
- 巧用DBGrid控件的Sort属性实现“点击标题栏自动排序功能”。(改进版本)
- 清华大学2017届本科毕业典礼演讲——做有思想的行者
- Hyperledger Fabric 节点类型Commiter、Endorser、Leader、Anchor
- JQuery安装与下载教程
- VideoEdit+ User Manual
- 马士兵Java自学之路
- PX4以往固件版本下载
- TiDB 在马上消费金融核心账务系统归档及跑批业务下的实践
- cdrx4自动排版步骤_教你怎样在CDR里怎样编号自动排版
- PostgreSQL小数修约
- 企鹅号转正后是2级账号还有用吗,企鹅号不被系统推荐怎么办
- EFR32 资源汇总