最长回文子串
META#
- URL: Leetcode.05 最长回文子串
- 难度: 中等
- 分类: 动态规划,字符串
描述#
给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。
示例 1:
输入: "babad"
输出: "bab"
注意: "aba" 也是一个有效答案。
示例 2:
输入: "cbbd"
输出: "bb"
回文就是倒着念正着念都一样的,如aba
倒过来念还是aba
。
动态规划#
一看这道题目就想起了动态规划。
对于子字符串s[i][j]
,如果s[i]==s[j]
,那么就看被ij包裹的里面的内容是不是回文,这就构成了递归式。
t(i,j) = s[i]==s[j] and t(i+1,j-1)
有递归就得有边界条件,如果i和j中间有一个字符或者没字符,那么就仅当s[i]==s[j]
时就是回文啦,比如aba
,aa
。所以可以推出个条件:j-i<3
的时候,结果是True
然后我们使用动态规划,需要构造一个二维数组t存储字符串是否是回文的状态。
class Solution:
def longestPalindrome(self,s: str) -> str:
size = len(s)
t = [[False for j in range(size)] for i in range(size)]
ml = 1
si = 0
for j in range(1,size):
for i in range(j):
if s[i] == s[j]:
if j - i < 3:
t[i][j] = True
else:
t[i][j] = t[i+1][j-1]
if t[i][j]:
cl = j - i + 1
if cl > ml:
ml = cl
si = i
return s[si:si+ml]
时间复杂度O(n2),空间复杂度O(n2)
中心扩展法#
此法时间复杂度也是O(n^2),只是空间复杂度变成了常数级别。
思路是对于字符串中的每一个字符,认为它是回文串的中心,那么只需查找两边的一样字符串的长度就可以确定以它为中心的回文串的长度。然后去找最大的一个。
class Solution:
def longestPalindrome(self,s: str)->str:
start,length = 0 ,0
for i in range(len(s)):
curLen = max(
self.getPalindromeLen(s,i,i),
self.getPalindromeLen(s,i,i+1)
)
if curLen > length:
start = i - (curLen-1) // 2
length = curLen
return s[start:start+length]
def getPalindromeLen(self,s: str,l:int,r:int)->int:
while l>=0 and r<len(s) and s[l] == s[r]:
l = l - 1
r = r + 1
return r - l - 1
需要注意的就是,因为双数长度的字符串的中心并没有字符,或者说在两个字符中间,比如aabb
的中心是aa#bb
,井号的位置。在算法中我们认为中间的两个字符是该字符串的中心。所以对于每个位置,要判断两次,一个是以当前位置为中心,一个是以当前位置和后一个字符为中心。
作者:Yudoge
出处:https://www.cnblogs.com/lilpig/p/12321200.html
版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。
欢迎按协议规定转载,方便的话,发个站内信给我嗷~
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· winform 绘制太阳,地球,月球 运作规律
· 上周热点回顾(3.3-3.9)