LeetCode 05最长回文子串

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

描述:

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


示例 1:

输入: “babad”

输出: “bab”

注意: “aba” 也是一个有效答案。


示例 2:

输入: “cbbd”

输出: “bb”


普通暴力



分析:


  • 求最长的回文串。而回文串又有奇数串和偶数串两种形式,我们只需要对有所情况从左到右进行枚举,然后返回最长的串即可。
  • 在编写代码的同时注意边界的问题不能越界。返回合理编号字符串。
  • 不要用String类型进行拼凑,因为String是不可变类每个拼凑都会生成一个新的字符串,多个拼凑会导致效率非常低下。


通过代码:


public String longestPalindrome(String s) {
    int max = 0;
    String va = "";
    if (s.length() > 0)
      va = s.charAt(0) + "";
    for (int i = 0; i < s.length() - 1; i++) {
      int l = i, r = i;//奇数个回文串
      while (l >= 0 && r <= s.length() - 1) {
        if (s.charAt(l) == s.charAt(r)) {
          l--;
          r++;
        } else {
          break;
        }
      }
      if (r - l + 1 > max) {
        max = r - l + 1;
        va = s.substring(l+1, r );
      }
      l = i;r = i + 1;//偶数个回文串
      if (s.charAt(i) == s.charAt(i + 1)) {
        while (l >= 0 && r <= s.length() - 1) {
          if (s.charAt(l) == s.charAt(r)) {
            l--;
            r++;
          } else {
            break;
          }
        }
      }
      if (r - l + 1 > max) {
        max = r - l + 1;
        va = s.substring(l+1, r );
      }
    }
    return va;
  }


中心扩散



最长回文串,能不能有什么优化的方案呢?


首先,最长可能出现在哪里呢?


  • 当然最长会出现在中间位置:


20200812172316918.png


如果第一次就找到这个最大的长度了,那么还需要查找其他不可能比它长的回文串了嘛?


  • 当然不需要。


使用什么方法能够确定不需要再查找更短的回文串了呢?


  • 从中间向两边查找,边查找边标记最大的回文串长度为max。
  • 如果向两边扩散时候该点到其中一个边界距离的二倍明显已经小于最长回文串的max长度,那就没必要计算了。可以直接停止。


20200812174724505.png


不过在具体的代码实现方面,要注意一些界限、特殊情况。ac代码为:


// 法二,中间扩散
  public static String getmaxhuiwen(int l,int r,String s) {
    if(l>r)return"";
    while (l >= 0 && r <= s.length() - 1) {
      if (s.charAt(l) == s.charAt(r)) {
        l--;
        r++;
      } else {
        break;
      }
    }
    return s.substring(l+1, r);
  }
  public  static String longestPalindrome(String s) {
    int max = 0;
    String va = "";
    if(s.length()<2)return s;//""和"a"
    int mid = (s.length()-1) / 2;//中间(偶数左侧,奇数中间)
    for (int i = 0; i < mid+1; i++) {
      int l = mid - i, r = l;//左奇数个
      String s1=getmaxhuiwen(l, r, s);
      va=va.length()>s1.length()?va:s1;
      l=mid-i;r=l+1;//左偶数个
      s1=getmaxhuiwen(l, r, s);
      va=va.length()>s1.length()?va:s1;
      l=mid+i;r=l;//右奇数个
      s1=getmaxhuiwen(l, r, s);
      va=va.length()>s1.length()?va:s1;
      l=mid+i;r=l+1;//右偶数个
      s1=getmaxhuiwen(l, r, s);
      va=va.length()>s1.length()?va:s1;
      max=va.length();//最大回文长度
      if(max>(mid-i+1)*2)//找不到更长直接返回
      {
        break;
      }
    }
    return va;
  }


这种情况效率已经不错了:


20200812180907943.png


结语



至于题解区有人提出动态规划的方法,但是动态规划在这题并没有太好的效率提高。这里就不作介绍了。


还有求回文串的马拉车算法,后面会专门写一篇记录学习和理解,敬请关注!

最后我请你们两连事帮忙一下:


  1. 点赞、关注一下支持, 您的肯定是我在平台创作的源源动力。
  2. 微信搜索「bigsai」,关注我的公众号,不仅免费送你电子书,我还会第一时间在公众号分享知识技术。加我还可拉你进力扣打卡群一起打卡LeetCode。


记得关注、咱们下次再见!

目录
相关文章
|
4月前
Leetcode第五题(最长回文子串)
这篇文章介绍了解决LeetCode第五题“最长回文子串”问题的一种方法,使用了中心扩展法来寻找给定字符串中的最长回文子串。
50 0
|
6月前
|
算法
LeetCode第5题最长回文子串
该文章介绍了 LeetCode 第 5 题最长回文子串的解法,通过分析回文子串的特点,使用动态规划的思想,用二维数组记录字符串是否为回文串,从后往前遍历找子串,减少重复判断,最终找到最长回文子串,并总结了解题时通过举例推导找规律的思路。
LeetCode第5题最长回文子串
|
6月前
|
Python
【Leetcode刷题Python】5. 最长回文子串
LeetCode 5题 "最长回文子串" 的Python解决方案,使用动态规划算法找出给定字符串中的最长回文子串。
57 3
|
8月前
dp表,哈希表,力扣5.最长回文子串力扣1745.分割回文串IV力扣132.分割回文串II优先级队列(堆)是什么下面是手动实现小根堆力扣1046.最后一块石头的重量
dp表,哈希表,力扣5.最长回文子串力扣1745.分割回文串IV力扣132.分割回文串II优先级队列(堆)是什么下面是手动实现小根堆力扣1046.最后一块石头的重量
|
8月前
|
存储 算法 Java
【经典算法】LeetCode 5: 最长回文子串(Java/C/Python3实现含注释说明,Medium)
【经典算法】LeetCode 5: 最长回文子串(Java/C/Python3实现含注释说明,Medium)
109 2
|
9月前
leetcode代码记录(最长回文子串
leetcode代码记录(最长回文子串
62 2
|
9月前
|
索引
力扣---最长回文子串(动态规划)
力扣---最长回文子串(动态规划)
|
9月前
|
存储 算法 Go
LeetCode第五题: 最长回文子串
给定一个字符串 `s`​,找到 `s`​ 中最长的回文子串。你可以假设 `s`​ 的最大长度为 1000。
LeetCode第五题: 最长回文子串
|
9月前
|
算法
LeetCode算法题---最长回文子串、N 字形变换(四)
LeetCode算法题---最长回文子串、N 字形变换(四)
49 0
|
9月前
|
算法 Go
golang力扣leetcode 5.最长回文子串
golang力扣leetcode 5.最长回文子串
68 1