每天 3 分钟,走上算法的逆袭之路。

前文合集

每日一道 LeetCode 前文合集

代码仓库

GitHub: https://github.com/meteor1993/LeetCode

Gitee: https://gitee.com/inwsy/LeetCode

题目:最长回文子串

难度:中等

题目来源:https://leetcode-cn.com/problems/longest-palindromic-substring/

给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。

示例 1:

  1. 输入: "babad"
  2. 输出: "bab"
  3. 注意: "aba" 也是一个有效答案。

示例 2:

  1. 输入: "cbbd"
  2. 输出: "bb"

解题方案一:暴力解法

暴力方案就很适合我这种脑子不够用的人,首先把字符串中的所有子串取出来,当然哈,取长度大于 1 的子串,不然也没啥意义。

然后挨个判断取出来的子串是否回文串,判断完了以后取到最大的那个,然后返回出来,结束。

  1. public String longestPalindrome(String s) {
  2. int len = s.length();
  3. if (len < 2) {
  4. return s;
  5. }
  6. // 先把字符串转成数组
  7. char[] charArray = s.toCharArray();
  8. // 定义初始位置
  9. int left = 0;
  10. // 定义字符串长度
  11. int length = 1;
  12. // 获取所有子串
  13. for (int i = 0; i < len - 1; i++) {
  14. for (int j = i + 1; j < len; j++) {
  15. if (j - i + 1 > length && valid(charArray, i, j)) {
  16. left = i;
  17. length = j - i + 1;
  18. }
  19. }
  20. }
  21. return s.substring(left, left + length);
  22. }
  23. // 判断是否回文串
  24. private boolean valid(char[] charArray, int left, int right) {
  25. while (left < right) {
  26. if (charArray[left] != charArray[right]) {
  27. return false;
  28. }
  29. left++;
  30. right--;
  31. }
  32. return true;
  33. }

这个答案慢肯定是慢,时间复杂度达到了 O(n^3) ,不慢才有鬼了。

解题方案二:中心扩散

上面的方案是从两边开始往中间夹,中心扩散的思想是从中间开始往两边进行扩散。

我在答案中找到了一个非常形象的图解,和大家分享一下:

解释一下这张图,现在假设有一个字符串 「acdbbdaa」 ,从第一个 b 位置开始找最长回文串。

  • 首先往左寻找与当期位置相同的字符,直到遇到不相等为止。
  • 然后往右寻找与当期位置相同的字符,直到遇到不相等为止。
  • 最后左右双向扩散,直到左和右不相等。

这时我们找到了从 b 开始最长的回文子串,然后在程序中记录下来。

每一个位置开始都按这个方案去找最长的回文子串,最后得到的结果就是最长的回文子串。

  1. public String longestPalindrome_1(String s) {
  2. if (s == null || s.length() == 0) return "";
  3. int length = s.length();
  4. // 定义左右指针
  5. int left = 0, right = 0;
  6. // 定义长度
  7. int len = 1;
  8. // 定义最大开始位置和最长子串长度
  9. int maxStart = 0, maxLen = 0;
  10. for (int i = 0; i < length; i++) {
  11. left = i - 1;
  12. right = i + 1;
  13. // 计算左边
  14. while (left >= 0 && s.charAt(left) == s.charAt(i)) {
  15. len++;
  16. left--;
  17. }
  18. // 计算右边
  19. while (right < length && s.charAt(right) == s.charAt(i)) {
  20. len++;
  21. right++;
  22. }
  23. // 两边一起扩散
  24. while (left >= 0 && right < length && s.charAt(left) == s.charAt(right)) {
  25. len += 2;
  26. left--;
  27. right++;
  28. }
  29. // 如果当前长度大于最大长度
  30. if (len > maxLen) {
  31. maxLen = len;
  32. maxStart = left;
  33. }
  34. // 下次循环前重置 len
  35. len = 1;
  36. }
  37. return s.substring(maxStart + 1, maxStart + 1 + maxLen);
  38. }

解题方案三:动态规划

动态规划我的理解实际上就是一个把已经判断过的信息缓存起来的一种方案,很像我们在做 Web 开发的时候用到的 redis ,只是在答案中换成了一个矩阵或者说是二维数组。

如果一个字符串 s[l, r] 是一个回文串,那么 s[l + 1, r - 1] 一定也是一个回文串,相当于两头各去掉一个字符。

如果这时我们直接通过某种方式直接可以知道 s[l + 1, r - 1] 是一个回文串,那么只需要判断 s[i] 和 s[j] 相等就可以了。

所以就有了下面的代码:

  1. public String longestPalindrome_2(String s) {
  2. if (s == null || s.length() == 0) return s;
  3. int length = s.length();
  4. int maxStart = 0; //最长回文串的起点
  5. int maxEnd = 0; //最长回文串的终点
  6. int maxLen = 1; //最长回文串的长度
  7. // 定义一个布尔矩阵
  8. boolean[][] dp = new boolean[length][length];
  9. for (int r = 1; r < length; r++) {
  10. for (int l = 0; l < r; l++) {
  11. if (s.charAt(r) == s.charAt(l) && (r - l <= 2 || dp[l + 1][r - 1] == true)) {
  12. dp[l][r] = true;
  13. if (r - l + 1 > maxLen) {
  14. maxLen = r - l + 1;
  15. maxStart = l;
  16. maxEnd = r;
  17. }
  18. }
  19. }
  20. }
  21. return s.substring(maxStart, maxEnd + 1);
  22. }

可以看到耗时也是蛮多的。

答案中还给出了一种叫做 Manacher 算法的方案,原谅我比较菜,属实是没看懂,就不拿出来献丑了。

每日一道 LeetCode (48):最长回文子串的更多相关文章

  1. LeetCode:最长回文子串【5】

    LeetCode:最长回文子串[5] 题目描述 给定一个字符串 s,找到 s 中最长的回文子串.你可以假设 s 的最大长度为1000. 示例 1: 输入: "babad" 输出: ...

  2. 【LeetCode】最长回文子串【动态规划或中心扩展】

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

  3. Java实现 LeetCode 5 最长回文子串

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

  4. [LeetCode] 5. 最长回文子串 ☆☆☆(最长子串、动态规划)

    最长回文子串 (动态规划法.中心扩展算法) https://leetcode-cn.com/problems/longest-palindromic-substring/solution/xiang- ...

  5. 【LeetCode】最长回文子串-中心扩展法

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

  6. leetcode python最长回文子串

    回文的意思是正着念和倒着念一样,如:上海自来水来自海上,雾锁山头山锁雾,天连水尾水连天 给定一个字符串 s,找到 s 中最长的回文子串.你可以假设 s 的最大长度为 1000. 示例 1: 输入: & ...

  7. [LeetCode] 5. 最长回文子串

    题目链接:https://leetcode-cn.com/problems/longest-palindromic-substring/ 题目描述: 给定一个字符串 s,找到 s 中最长的回文子串.你 ...

  8. LeetCode 05 最长回文子串

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

  9. 【leetcode 5. 最长回文子串】解题报告

    方法一:中心扩展算法 解题思路:从左到右每一个字符都作为中心轴,然后逐渐往两边扩展,只要发现有不相等的字符,则确定了以该字符为轴的最长回文串,但需要考虑长度为奇数和偶数的不同情况的处理(长度为偶数时轴 ...

  10. 【LeetCode】最长回文子串-动态规划法

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

随机推荐

  1. unity探索者之protobuf的序列化和反序列化导致unity崩溃的问题研究

    版权声明:本文为原创文章,转载请声明http://www.cnblogs.com/unityExplorer/p/7574569.html 这两天博主在接微信支付SDK的时候碰到一个非常恶心又诡异的问 ...

  2. 汇编in和out实例解析

    直接看例子: IN AL,21H 从21H端口读取一字节数据到AL IN AX,21H 从端口地址21H读取1字节数据到AL,从端口地址22H读取1字节到AH MOV DX,379HIN AL,DX ...

  3. bluetoothctl命令提示No default controller available

    在学习bluetoothctl命令时,执行bluetoothctl,然后执行show,提示No default controller available. 1. 执行hciconfig,发现有hci0 ...

  4. I帧B帧P帧

    转载自:http://blog.csdn.net/abcjennifer/article/details/6577934 视频压缩中,每帧代表一幅静止的图像.而在实际压缩时,会采取各种算法减少数据的容 ...

  5. MySQL数据库练习题

    表结构 DROP DATABASE IF EXISTS test1; CREATE DATABASE test1; USE test1; ##部门表 #DROP IF EXISTS TABLE DEP ...

  6. lx

    自我介绍:我是18软件技术5班 张震. -统计截止目前为止我自己写过代码3000行,我希望在本课结束后累计到10000行代码, 选择自测题17分,错题大多是运算符和运算符先 后级一类的题,编程题不会, ...

  7. NeuroAttack: Undermining Spiking Neural Networks Security through Externally Triggered Bit-Flips

    郑重声明:原文参见标题,如有侵权,请联系作者,将会撤销发布! arXiv:2005.08041v1 [cs.CR] 16 May 2020 Abstract 由于机器学习系统被证明是有效的,因此它被广 ...

  8. (新手向)N皇后问题详解(DFS算法)

    非常经典的一道题: N皇后问题: 国际象棋中皇后的势力范围覆盖其所在的行.列以及两条对角线,现在考察如下问题:如何在n x n的棋盘上放置n个皇后,使得她们彼此互不攻击 . 免去麻烦我们这里假定n不是 ...

  9. ClassFile与JClass

    本次大作业中 java程序——>二进制流(byte[ ]表示)——>ClassFile对象——>JClass ClassFile的字段:magic,minorversion..... ...

  10. 不要再问我 in,exists 走不走索引了

    微信搜『烟雨星空』,获取最新好文. 前言 最近,有一个业务需求,给我一份数据 A ,把它在数据库 B 中存在,而又比 A 多出的部分算出来.由于数据比较杂乱,我这里简化模型. 然后就会发现,我去,这不 ...