力扣-最长回文子串

最长回文子串

题目描述

题目链接:https://leetcode-cn.com/problems/longest-palindromic-substring/

难度:中等

(吐槽一下,上一题的寻找中位数都是困难,这题不也应该是个困难吗)

给你一个字符串 s,找到 s 中最长的回文子串。

解析

  • 方法一:最暴力的情况,枚举左右端点两重循环,判断字符串是否是回文串一重循环,复杂度\(O(n^3)\)
  • 方法二:DP,此处先不展开,复杂度\(O(n^2)\)
  • 方法三:我比较喜欢的做法,我称之为中心点扩展法,复杂度也是\(O(n^2)\),就是常数比DP大一点,但是没开DP数组,算是时间换空间了。

方法:首先通过一重循环枚举回文串的中心点,这里分两种情况:单字符作为中心点的如 abab;其次是双字符作为中心点的如abbabb。枚举到了就往外扩张,每次增加左右的两个字符,因为已经保证了中心点已经是回文串了,如果新加入的左右两个字符正好相等,那么加入进来可以保证新串也是回文的。由于扩展的复杂度也是\(O(n)\),两个套一起就是\(O(n^2)\)

代码

class Solution:
    def longestPalindrome(self, s: str) -> str:
        max_len = 1
        max_left, max_right = 0, 0

        str_len = len(s)

        for idx in range(str_len):
            # 枚举单字符中心点,并向外扩张
            left, right = idx - 1, idx + 1

            while True:
                if left < 0 or right >= str_len:  # 越界
                    break

                if s[left] != s[right]:
                    break

                if max_len < right - left + 1:
                    max_len = right - left + 1
                    max_left, max_right = left, right

                left, right = left - 1, right + 1

        for idx in range(str_len - 1):
            # 枚举双字符中心点,并向外扩张,此处对应中心为两个相同的字符
            if s[idx] != s[idx + 1]:
                continue

            left, right = idx, idx + 1 
            # 由于初始化的时候设置了最小值为 1 ,因此这里需要从判断下
            # 最小双字符是否比原来的长,不能设置为 idx - 1 和 idx + 2

            while True:
                if left < 0 or right >= str_len:  # 越界
                    break

                if s[left] != s[right]:
                    break

                if max_len < right - left + 1:
                    max_len = right - left + 1
                    max_left, max_right = left, right


                left, right = left - 1, right + 1
        
        return s[max_left: max_right + 1]

总结

暴力出奇迹,乱搞押正解,骗分最神奇,打标拿第一(雾~o(///▽///)q

posted @ 2022-01-19 17:13  XBCoder  阅读(36)  评论(0)    收藏  举报