题目:
解法一:双指针遍历(从外向内)
思路:
从最大子串(自身)开始遍历,逐渐缩小子串长度(右边界right向左移),对于每一个长度要注意遍历该长度下的所有子串
代码:
class Solution_double:
def longestPalindrome(self, s: str) -> str:
def judge(i, j) -> bool:
while i < j:
if s[i] != s[j]:
return False
i += 1
j -= 1
return True
l = len(s)
left, right = 0, len(s)-1
while left <= right:
i, j = left, right
while j <= len(s)-1: # 右指针向右移使得遍历每一个该长度的子串
if judge(i, j):
return s[i:j+1]
else:
i += 1
j += 1
right -= 1
解法二:中心扩散法(从内向外)
思路:
对于每一单个字符来说,都有成为对称中心的潜质,(如果是偶数个相同字符则将其看成单个就行),遍历每一个字符,求每一个字符下的最大向外延伸长度
代码
class Solution_center:
def longestPalindrome(self, s: str) -> str:
l = len(s)
max_l = 0
ret = -1
for i in range(l):
my = [i, i]
while i+1 < l and s[i] == s[i+1]: # 保证双中心的情况
my[1] += 1
i += 1
while my[0] > 0 and my[1] < l-1:
if s[my[0]-1] == s[my[1]+1]:
my[0] -= 1
my[1] += 1
else:
break
if my[1]-my[0]+1 > max_l:
ret = my
max_l = my[1]-my[0]+1
return s[ret[0]:ret[1]+1]
解法三:动态规划
思路:
刚看到这道题的时候想过用动态规划,很容易可以想到这道题在动态规划下的转移方程(前一状态加上外面两个字符满足情况),但是没想到具体用什么样的dp来维护结果数组,所以该题的关键就在这里,用dp[i][j]来储存从i到j上是否为满足情况的解(回文)
代码:
class Solution_dp:
def longestPalindrome(self, s: str) -> str:
l = len(s)
dp = [[False]*l for _ in range(l)]
max_l = 1
max_s = s[0]
for i in range(l):
dp[i][i] = True
for L in range(2, l+1):
for i in range(l):
j = i + L - 1
if j > l-1:
break
if s[i] == s[j]:
if L > 2:
dp[i][j] = dp[i+1][j-1]
else:
dp[i][j] = True
if L > max_l and dp[i][j]:
max_s = s[i:j+1]
max_l = L
return max_s
作者:mhuang
链接:https://leetcode-cn.com/problems/longest-palindromic-substring/solution/dong-tai-gui-hua-zhong-xin-kuo-san-fa-co-4o3s/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。