题目要求
思路:
- 如果a是回文字符串,那么如果 a的左侧字符=a的右侧字符 ,【a左侧字符+a+a的右侧字符】也是一个回文串
- 同理,如果bab是回文字符串,那么 如果最左侧b的左侧字符 = 最右侧的b的右侧字符,那么【最左侧b的左侧字符 + bab +最右侧的b的右侧字符】也是一个回文字符串
所以可以编写一个函数get_str,给定已知回文子字符串的最小下标和最右下标,然后横向扩散去寻找回文字符串。
- 例如 字符串 s = "babad",b的下标为2,b为一个回文子字符串,那么把2作为字符串的左下标left,2同时作为字符串的右下标right,让函数get_str去向左向右寻找,如果left > 0 and right < len(s) and s[left] == s[right],就让left - 1,right + 1,然后在比较s[left-1]与s[right+1]是否相等,且下标不超过0和len(s)
那么如何确定要给get_str什么样的下标呢,可以通过遍历字符串s
每遍历到一个字符,有两种情况
- 1、这个字符是中心字符,例如bab,a就是中心字符,那么给get_str的左下标和右下标都是a的下标
- 2、这个字符和这个字符的下一个字符共同组成中心字符,例如,baab,那么给get_str,左侧a的下标作为左下标,右侧a的下标作为右下标
- 还需要有两个变量,start,end,用来保存当前最长子回文串的左下标和右下标,如果get_str找到比当前临时保存的子字符串更长的回文串,要更新start和end,最后返回s[start,end + 1](因为s[start:end]会不算上end)
- 核心代码
class Solution:
def longestPalindrome(self, s: str) -> str:
def get_str(left, right, s):
while left >= 0 and right < len(s) and s[left] == s[right]:
left -= 1
right += 1
# 返回left+1和right-1是因为最后一次while循环会对left多减一,对right多+1,这时的left和right左右会多各多算一个字符
return left + 1, right - 1
start, end = 0, 0
for i in range(len(s)):
# 两种情况
left1, right1 = get_str(i, i, s)
left2, right2 = get_str(i, i + 1, s)
# 如果搜索到比当前回文子字符串更长的,就要更新
if right1 - left1 > end -start:
start, end = left1, right1
if right2 - left2 > end -start:
start, end = left2, right2
return s[start:end + 1]
完整代码
class Solution:
def longestPalindrome(self, s: str) -> str:
def get_str(left, right, s):
while left >= 0 and right < len(s) and s[left] == s[right]:
left -= 1
right += 1
return left + 1, right - 1
start, end = 0, 0
for i in range(len(s)):
left1, right1 = get_str(i, i, s)
left2, right2 = get_str(i, i + 1, s)
if right1 - left1 > end -start:
start, end = left1, right1
if right2 - left2 > end -start:
start, end = left2, right2
return s[start:end + 1]
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。