力扣-最长回文子串
最长回文子串
题目描述
题目链接:https://leetcode-cn.com/problems/longest-palindromic-substring/
难度:中等
(吐槽一下,上一题的寻找中位数都是困难,这题不也应该是个困难吗)
给你一个字符串
s,找到s中最长的回文子串。
解析
- 方法一:最暴力的情况,枚举左右端点两重循环,判断字符串是否是回文串一重循环,复杂度\(O(n^3)\)。
- 方法二:DP,此处先不展开,复杂度\(O(n^2)\)
- 方法三:我比较喜欢的做法,我称之为中心点扩展法,复杂度也是\(O(n^2)\),就是常数比DP大一点,但是没开DP数组,算是时间换空间了。
方法:首先通过一重循环枚举回文串的中心点,这里分两种情况:单字符作为中心点的如 aba 的b;其次是双字符作为中心点的如abba的bb。枚举到了就往外扩张,每次增加左右的两个字符,因为已经保证了中心点已经是回文串了,如果新加入的左右两个字符正好相等,那么加入进来可以保证新串也是回文的。由于扩展的复杂度也是\(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

浙公网安备 33010602011771号