【问题描述】[第5题][最长回文子串][中等]

给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。示例 1:输入: "babad"
输出: "bab"
注意: "aba" 也是一个有效答案。

【解答思路】

1. 中心扩展法



时间复杂度:O(N^2) 空间复杂度:O(1)

public class Solution {public String longestPalindrome(String s) {int len = s.length();if (len < 2) {return s;}int maxLen = 1;String res = s.substring(0, 1);// 中心位置枚举到 len - 2 即可for (int i = 0; i < len - 1; i++) {String oddStr = centerSpread(s, i, i);String evenStr = centerSpread(s, i, i + 1);String maxLenStr = oddStr.length() > evenStr.length() ? oddStr : evenStr;if (maxLenStr.length() > maxLen) {maxLen = maxLenStr.length();res = maxLenStr;}}return res;}private String centerSpread(String s, int left, int right) {// left = right 的时候,此时回文中心是一个字符,回文串的长度是奇数// right = left + 1 的时候,此时回文中心是一个空隙,回文串的长度是偶数int len = s.length();int i = left;int j = right;while (i >= 0 && j < len) {if (s.charAt(i) == s.charAt(j)) {i--;j++;} else {break;}}// 这里要小心,跳出 while 循环时,恰好满足 s.charAt(i) != s.charAt(j),因此不能取 i,不能取 jreturn s.substring(i + 1, j);}
}
2.暴力
  • 根据回文子串的定义,枚举所有长度大于等于 22 的子串,依次判断它们是否是回文;
  • 在具体实现时,可以只针对大于“当前得到的最长回文子串长度”的子串进行“回文验证”;
  • 在记录最长回文子串的时候,可以只记录“当前子串的起始位置”和“子串长度”

时间复杂度:O(N^3) 空间复杂度:O(1)

public class Solution {public String longestPalindrome(String s) {int len = s.length();if (len < 2) {return s;}int maxLen = 1;int begin = 0;// s.charAt(i) 每次都会检查数组下标越界,因此先转换成字符数组char[] charArray = s.toCharArray();// 枚举所有长度大于 1 的子串 charArray[i..j]for (int i = 0; i < len - 1; i++) {for (int j = i + 1; j < len; j++) {if (j - i + 1 > maxLen && validPalindromic(charArray, i, j)) {maxLen = j - i + 1;begin = i;}}}return s.substring(begin, begin + maxLen);}/*** 验证子串 s[left..right] 是否为回文串*/private boolean validPalindromic(char[] charArray, int left, int right) {while (left < right) {if (charArray[left] != charArray[right]) {return false;}left++;right--;}return true;}
}
3. 动态规划




时间复杂度:O(N^2) 空间复杂度:O(N)

public class Solution {public String longestPalindrome(String s) {// 特判int len = s.length();if (len < 2) {return s;}int maxLen = 1;int begin = 0;// dp[i][j] 表示 s[i, j] 是否是回文串boolean[][] dp = new boolean[len][len];char[] charArray = s.toCharArray();for (int i = 0; i < len; i++) {dp[i][i] = true;}for (int j = 1; j < len; j++) {for (int i = 0; i < j; i++) {if (charArray[i] != charArray[j]) {dp[i][j] = false;} else {if (j - i < 3) {dp[i][j] = true;} else {dp[i][j] = dp[i + 1][j - 1];}}// 只要 dp[i][j] == true 成立,就表示子串 s[i..j] 是回文,此时记录回文长度和起始位置if (dp[i][j] && j - i + 1 > maxLen) {maxLen = j - i + 1;begin = i;}}}return s.substring(begin, begin + maxLen);}
}

【总结】

1. 想法优先暴力 逐渐优化 不要东想西想
2.动态规划

1、思考状态(重点)

状态的定义,先尝试「题目问什么,就把什么设置为状态」;
然后思考「状态如何转移」,如果「状态转移方程」不容易得到,尝试修改定义,目的依然是为了方便得到「状态转移方程」。
「状态转移方程」是原始问题的不同规模的子问题的联系。即大问题的最优解如何由小问题的最优解得到。

2、思考状态转移方程(核心、难点)

状态转移方程是非常重要的,是动态规划的核心,也是难点;

常见的推导技巧是:分类讨论。即:对状态空间进行分类;

归纳「状态转移方程」是一个很灵活的事情,通常是具体问题具体分析;

除了掌握经典的动态规划问题以外,还需要多做题;

如果是针对面试,请自行把握难度。掌握常见问题的动态规划解法,理解动态规划解决问题,是从一个小规模问题出发,逐步得到大问题的解,并记录中间过程;

「动态规划」方法依然是「空间换时间」思想的体现,常见的解决问题的过程很像在「填表」。

3、思考初始化

初始化是非常重要的,一步错,步步错。初始化状态一定要设置对,才可能得到正确的结果。

角度 1:直接从状态的语义出发;

角度 2:如果状态的语义不好思考,就考虑「状态转移方程」的边界需要什么样初始化的条件;

角度 3:从「状态转移方程」方程的下标看是否需要多设置一行、一列表示「哨兵」(sentinel),这样可以避免一些特殊情况的讨论。

4、思考输出

有些时候是最后一个状态,有些时候可能会综合之前所有计算过的状态。

5、思考优化空间(也可以叫做表格复用)

「优化空间」会使得代码难于理解,且是的「状态」丢失原来的语义,初学的时候可以不一步到位。先把代码写正确是更重要;
「优化空间」在有一种情况下是很有必要的,那就是状态空间非常庞大的时候(处理海量数据),此时空间不够用,就必须「优化空间」;
非常经典的「优化空间」的典型问题是「0-1 背包」问题和「完全背包」问题。

3. 动态规划思考
  • 边界问题考虑清楚(第二第三步)
  • 动态就是做表格 想清楚方向
  • 自底向上 子问题 学基础 再解决问题 通识教育
  • 自顶向下 一般解决问题思路

转载链接:https://leetcode-cn.com/problems/longest-palindromic-substring/solution/zhong-xin-kuo-san-dong-tai-gui-hua-by-liweiwei1419/

[Leedcode][JAVA][第5题][最长回文子串][数组][动态规划]相关推荐

  1. leetcode算法题--最长回文子串

    题目链接:https://leetcode-cn.com/problems/longest-palindromic-substring/ 相关题目:最长回文子序列 动态规划 dp[i][j]表示从i到 ...

  2. leetcode5. 最长回文子串(动态规划)

    给定一个字符串 s,找到 s 中最长的回文子串.你可以假设 s 的最大长度为 1000. 示例 1: 输入: "babad" 输出: "bab" 注意: &qu ...

  3. LeetCode 5. 最长回文子串(动态规划)

    文章目录 1. 题目 2. 解题 2.1 自己写的DP 2.2 优化后的DP 2.3 中心扩展法 1. 题目 给定一个字符串 s,找到 s 中最长的回文子串.你可以假设 s 的最大长度为 1000. ...

  4. 求最长回文子串——C++ (动态规划+暴力解法)

    声明:本文原题主要来自力扣,记录此博客主要是为自己学习总结,不做任何商业等活动! 一.题目描述 给你一个字符串 s,找到 s 中最长的回文子串. 示例 1: 输入:s = "babad&qu ...

  5. 每日一道Leetcode - 5. 最长回文子串 【动态规划】

    class Solution:def longestPalindrome(self, s: str) -> str:"""# 对于长度大于2的字符串,我们认为去掉首 ...

  6. LeetCode琅琊榜第二层-最长回文子串问题(动态规划)

    LeetCode_5.最长回文字串 难度:中等 关注博主,持续输出优质算法内容 题目链接 目录 1.暴力求解法

  7. LeetCode刷题——最长回文子串

    目录 一.题目描述 二.题解 三.源码 一.题目描述 二.题解 三.源码 class Solution(object):def longestPalindrome(self, s):"&qu ...

  8. 最长回文子串 : Marcher算法

    相应leetcode题目 leetcode 第5题. 最长回文子串 1.回文串 即从两边开始到中间,对应的字符都相同 public boolean isPalindrome(String str){i ...

  9. LeetCode 516. 最长回文子序列(动态规划)

    1. 题目 给定一个字符串s,找到其中最长的回文子序列.可以假设s的最大长度为1000. 示例 1: 输入: "bbbab" 输出: 4 一个可能的最长回文子序列为 "b ...

最新文章

  1. Redis将继续采用BSD许可证
  2. instanceof 的作用
  3. 牛客(35)数组中的逆序对
  4. python基础学习笔记2
  5. 微信小程序消息推送自有服务器无法接收到信息,消息推送服务器配置次数用完的解决方式。
  6. 【JEECG技术博文】Jeecg高级查询器
  7. mysql数据库导入导出和密码修改
  8. 阿里云祝顺民:云网络心智大图解读 | 云栖大会
  9. 【人脸表情识别】基于matlab PCA+SVM人脸表情识别评分系统【含Matlab源码 593期】
  10. JVM监控及诊断工具命令行篇之jmap
  11. matlab pdetool解热传导方程,传热学与应用(李晓炜)基于pdetool的热传导数值计算.pdf...
  12. mysql用reader读取空数据时报错的处理
  13. 百度万年历API(主要获取节假日和调休工作日数据)
  14. 三菱plc pwm指令_【三菱PLC指令教程】定时器指令应用之时序图编程法(一)
  15. java生成mib文件_Mib浏览器设计(附源码) | 学步园
  16. 【腾讯敏捷转型No.7】QQ邮箱如何通过敏捷成为行业第一
  17. 吴恩达神经网络与深度学习——深度神经网络
  18. realmeq参数配置详情_realmeq参数配置-realmeq手机性能规格详情
  19. Python笔记六、文件和数据格式化
  20. 爆笑课堂:程序员看得懂的搞笑段子

热门文章

  1. java---sychronized的深入理解
  2. 在caffe中使用hdf5的数据
  3. 回复《我要阻止做java开发的男朋友去创业型公司工作吗?》园友问题
  4. jremind V0.1.3.0添加透明
  5. 设置公共请求参数_基于分布式锁的防止重复请求解决方案(值得收藏)
  6. 会移动的文字(Marquee)
  7. tk-mapper 生成器
  8. docker php示例,Docker PHP 例子
  9. 【C语言进阶深度学习记录】二十六 C语言中的字符串与字符数组的详细分析
  10. Java枚举类型 enum