1 中心奇偶扩展法
-
1.奇数长度中心扩展
- 设置左右指针,不能超出字符串的边界
-
1.偶数长度中心扩展
- i,i+1为中心
- 注意length提前定义
-
2.遍历,res = max(odd, even res)得到最终答案
# -*- coding:utf-8 -*-
class Solution:
def getLongestPalindrome(self, A, n):
# write code here
def expandOdd(i, A):
l, r = i, i
while l >= 0 and r < len(A):
if A[l] == A[r]:
length = r - l + 1
l -= 1
r += 1
else:
break
return length
def expandEven(i, j, A):
l, r = i, j
length = 0 #这里必需要定义一下,因为,下面的循环可能不会走就return length,会报错length没有定义
while l >=0 and r < len(A):
if A[l] == A[r]:
length = r - l + 1
l -= 1
r += 1
else:
break
return length
res = 1
for i in range(n):
res = max(res, expandOdd(i, A))
res = max(res, expandEven(i, i+1, A))
return res
2 递归
过不了
class Solution:
def isPalindrome(self, A):
l, r = 0, len(A)-1
while l < r:
if A[l] == A[r]:
l += 1
r -= 1
else:
return False
return True
def getLongestPalindrome(self, A, n):
# write code here
if self.isPalindrome(A):
return len(A)
return max(self.getLongestPalindrome(A[1:], n-1),self.getLongestPalindrome(A[:-1], n-1))
3 区间动态规划
dp[i,j] = (A[i] == A[j] ) and dp[i+1, j-1], j-1 > i+1
# -*- coding:utf-8 -*-
class Solution:
def getLongestPalindrome(self, A, n ):
if n < 2:
return A
max_len = 1
begin = 0
# dp[i][j] 表示 s[i..j] 是否是回文串
dp = [[False] * n for _ in range(n)]
for i in range(n):
dp[i][i] = True
# 递推开始
# 先枚举子串长度
for L in range(2, n + 1):
# 枚举左边界,左边界的上限设置可以宽松一些
for i in range(n):
# 由 L 和 i 可以确定右边界,即 j - i + 1 = L 得
j = L + i - 1
# 如果右边界越界,就可以退出当前循环
if j >= n:
break
if A[i] != A[j]:
dp[i][j] = False #如果i,j对应字符不相等,那就不是回文串
else: #如果相等,直接确认是回文串
if j - i < 3:
dp[i][j] = True
else:
dp[i][j] = dp[i + 1][j - 1] # j-1 >= i+1 => j-i-2 >=0 => j-i >=2
# 只要 dp[i][L] == true 成立,就表示子串 s[i..L] 是回文,此时记录回文长度和起始位置
if dp[i][j] and j - i + 1 > max_len:
max_len = j - i + 1
begin = i
return max_len