【算法训练】LeetCode#5 最长回文子串
一、描述
给你一个字符串 s
,找到 s
中最长的回文子串。
输入:s = "babad"
输出:"bab"
解释:"aba" 同样是符合题意的答案。
示例 2:
输入:s = "cbbd"
输出:"bb"
二、思路
- 中心扩散,从第一位开始,遵从左右左的方式扩散
- 扩散时将做过判断的字符串放入备选数组,防止重复判断
- 当得到回文子串时,记录长度,下次扩散直接从等长开始
三、解题
中心扩散,只能通过50%,输入样例为下面这个时,会超时(本地运行为0.4秒)
kyyrjtdplseovzwjkykrjwhxquwxsfsorjiumvxjhjmgeueafubtonhlerrgsgohfosqssmizcuqryqomsipovhhodpfyudtusjhonlqabhxfahfcjqxyckycstcqwxvicwkjeuboerkmjshfgiglceycmycadpnvoeaurqatesivajoqdilynbcihnidbizwkuaoegmytopzdmvvoewvhebqzskseeubnretjgnmyjwwgcooytfojeuzcuyhsznbcaiqpwcyusyyywqmmvqzvvceylnuwcbxybhqpvjumzomnabrjgcfaabqmiotlfojnyuolostmtacbwmwlqdfkbfikusuqtupdwdrjwqmuudbcvtpieiwteqbeyfyqejglmxofdjksqmzeugwvuniaxdrunyunnqpbnfbgqemvamaxuhjbyzqmhalrprhnindrkbopwbwsjeqrmyqipnqvjqzpjalqyfvaavyhytetllzupxjwozdfpmjhjlrnitnjgapzrakcqahaqetwllaaiadalmxgvpawqpgecojxfvcgxsbrldktufdrogkogbltcezflyctklpqrjymqzyzmtlssnavzcquytcskcnjzzrytsvawkavzboncxlhqfiofuohehaygxidxsofhmhzygklliovnwqbwwiiyarxtoihvjkdrzqsnmhdtdlpckuayhtfyirnhkrhbrwkdymjrjklonyggqnxhfvtkqxoicakzsxmgczpwhpkzcntkcwhkdkxvfnjbvjjoumczjyvdgkfukfuldolqnauvoyhoheoqvpwoisniv
from sys import flags
from typing import List
class Solution:
inputS = ""
overS = []
maxSum = 0
maxStr = ""
sLen = 0
def longestPalindrome(self, s: str) -> str:
self.inputS = s
self.sLen = len(s)
for i in range(self.sLen):
self.getCurrent(i)
if self.sLen == 1 or self.maxSum == 0:
return s[0]
return self.maxStr
def getCurrent(self,currentLoc):
# 获取当前位置左右扩展字符串,通过调用judHui判断回文
flags = False
leftLoc = currentLoc
rightLoc = currentLoc
while True:
if flags:
rightLoc += 1
else:
leftLoc -= 1
flags = not flags
if leftLoc < 0 or rightLoc > self.sLen -1:
break
if rightLoc - leftLoc + 1 < self.maxSum:
# 长度小于最大长度就不做判断
continue
self.judHui(leftLoc,rightLoc)
def judHui(self,leftLoc,rightLoc):
tempLeft = leftLoc
tempRight = rightLoc
# 通过左右坐标判断当前字符串是否为回文字符串
while rightLoc >= leftLoc:
if self.inputS[rightLoc] != self.inputS[leftLoc]:
self.overS.append(self.inputS[tempLeft:tempRight+1]) # 判断过的不再判断
return
rightLoc -= 1
leftLoc += 1
else:
# 是回文
if tempRight - tempLeft + 1 > self.maxSum:
self.maxSum = tempRight - tempLeft + 1
self.maxStr = self.inputS[tempLeft:tempRight+1]
self.overS.append(self.inputS[tempLeft:tempRight+1]) # 判断过的不再判断
return
上面这种写法有太多重复性判断了,导致超时....
class Solution:
inputS = ""
maxSum = 0
maxStr = ""
sLen = 0
def longestPalindrome(self, s: str) -> str:
self.inputS = s
self.sLen = len(s)
if self.sLen == 1:
return s[0]
if self.sLen == 2:
if s[0] == s[1]:
return s
else:
return s[0]
for i in range(self.sLen):
self.getCurrent(i)
if self.maxSum == 0:
return s[0]
return self.maxStr
def getCurrent(self,currentLoc):
# 获取当前位置左右扩展字符串,通过调用judHui判断回文
leftLoc,rightLoc = currentLoc,currentLoc
curLen = 1
# 先找到当前位置左右相同的界限,将界限作为起始扩散位置
while True:
while leftLoc > 0 and self.inputS[leftLoc-1] == self.inputS[currentLoc]:
curLen += 1
leftLoc -= 1
while rightLoc < self.sLen - 1 and self.inputS[rightLoc+1] == self.inputS[currentLoc]:
curLen += 1
rightLoc += 1
if curLen > self.maxSum:
self.maxSum = curLen
self.maxStr = self.inputS[leftLoc:rightLoc+1]
break
while True:
leftLoc -= 1
rightLoc += 1
if leftLoc < 0 or rightLoc > self.sLen - 1:
break
if self.inputS[rightLoc] != self.inputS[leftLoc]:
return
else:
curLen += 2
if curLen > self.maxSum:
self.maxSum = curLen
self.maxStr = self.inputS[leftLoc:rightLoc+1]