LeetCode最长回文子串
题目描述:
给你一个字符串 s
,找到 s
中最长的回文子串。
示例 1:
输入:s = "babad"
输出:"bab"
解释:"aba" 同样是符合题意的答案。
示例 2:
输入:s = "cbbd"
输出:"bb"
示例 3:
输入:s = "a"
输出:"a"
示例 4:
输入:s = "ac"
输出:"a"
思路分析
回文串问题算是非常典型常见的题目了。这道题要找最长回文子串,其实有一个非常经典高效的算法:马拉车算法,时间复杂度和空间复杂度都为O(n),不过马拉车算法就是太巧妙了,巧妙到只适合这一个问题,可扩展或者可借鉴的地方不是很多,往往这种奇技淫巧记住了也容易忘,有兴趣的可以去搜一下了解了解;还有一种方法就是动态规划,但比较搞笑的是,用动态规划解决这一问题,是简洁和复杂度低两样都不占(其时空复杂度都是O(n的平方),如果用动态规划,更像是强行“炫技“了。后面会有很多动态规划的题目,到时候再去体会动态规划的魅力吧。
我自己总结这些算法题,从来都不是追求最优解,而是追求最优和容易记忆之间的平衡,毕竟面试遇到的时候,可以第一时间想到一个较为合适的解才是最重要的。
这道题最“不错“的解法是中心扩散法。不要被它这个名字吓到了,其实很简单,我描述一遍:遍历给定的字符串,从前向后遍历字符,以它以及它和它的下一个为中心尝试向两边扩散,看看是不是满足是回文串,如果是就继续扩散,直到不满足,记录下最大长度。这里之所以要分别以(它)以及(它和它的下一个)为中心,是因为回文串有的是“aba”,有的是“abba”,即中心可能包含一个或两个字符,所以要都要进行讨论。
这样一来,最外面遍历一次,每个字符也要向两边扩散遍历,总复杂度为O(n的平方)。
代码:
class Solution(object):
def longestPalindrome(self, s):
"""
:type s: str
:rtype: str
"""
def is_hui(s,i,j):#传入字符串s,和当前左右边界i和j,返回以i,j位置为中心的最长回文子串
lenth = len(s)
#如果满足回文条件且为超过边界,就一直扩散
while(i>=0 and j<=lenth-1 and s[i]==s[j]):
i-=1 #扩散方式就是i减小,j增大
j+=1
return [i+1,j,j-i-1]#注意边界要单独处理一下,以列表的形式返回,分别是左边界、右边界和长度
res=0 #res保存最终结果
res_i=0
res_j=0
for i in range(len(s)):
a =is_hui(s,i,i) #以i位置单个字符为中心
if a[-1]>res:#如果此时的长度超过历史记录,则更新
res = a[-1]
res_i=a[0]
res_j=a[1]
a = is_hui(s,i,i+1)#以i和i的下一个双字符为中心
if a[-1]>res:#如果此时的长度超过历史记录,则更新
res = a[-1]
res_i=a[0]
res_j=a[1]
#res_i,res_j就是最终结果的左右边界了
return s[res_i:res_j]
总之,解这个题方法很多,但我推荐中心扩散法这种简单理解并记忆的方法,尤其是方便记忆,这个优点很重要。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了