描述
给出一个字符串(假设长度最长为1000),求出它的最长回文子串,你可以假定只有一个满足条件的最长回文串。
样例
样例 1:
输入:“abcdzdcab”
输出:“cdzdc”
样例 2:
输入:“aba”
输出:“aba”
挑战
O(n2) 时间复杂度的算法是可以接受的,如果你能用 O(n) 的算法那自然更好。
方法一:中心点枚举
注意:要考虑中心点是一个数(比如: aba)和两个数(比如:abba)的情况。如果不清楚是+1还是-1,找个实例验证一下
class Solution:
"""
@param s: input string
@return: a string as the longest palindromic substring
"""
def find_longest_palindrome_from(self, s, left, right):
while left >= 0 and right < len(s) and s[left] == s[right]:
left -= 1
right += 1
return right - left - 1
def longestPalindrome(self, s):
if s is None or len(s) == 0:
return ""
start = 0
longest_len = 0
for i in range(len(s)):
length = self.find_longest_palindrome_from(s, i, i)
if length > longest_len:
start = i - (length - 1) // 2
longest_len = length
length = self.find_longest_palindrome_from(s, i, i+1)
if length > longest_len:
start = i - (length - 1) // 2
longest_len = length
return s[start: start + longest_len]
方法二:动态规划
注意:遍历字符串获得子字符串时,应当先从后往前遍历
解析见图片(标题是错的,应为longest palindrome)
class Solution:
"""
@param s: input string
@return: a string as the longest palindromic substring
"""
def longestPalindrome(self, s):
#dp[i,j] represents that if substring from i to j is palindrome
#if dp[i+1][j-1] and s[i] == s[j]: dp[i,j] = True; else dp[i,j]
# write your code here
if s is None:
return None
if len(s) <= 1:
return s
n = len(s)
dp = [[0] * n for _ in range(n)]
start = 0
longest_len = 0
#aba
for i in range(n):
dp[i][i] = True
if dp[i][i]:
start = i
longest_len = 1
#abba
for i in range(n-1):
dp[i][i+1] = s[i] == s[i + 1]
if dp[i][i+1]:
start = i
longest_len = 2
#?a[bb]a?
for i in range(n-2, -1, -1):
for j in range(i + 2, n):
dp[i][j] = dp[i+1][j-1] and s[i] == s[j]
if dp[i][j] and j - i + 1 > longest_len:
start = i
longest_len = j - i + 1
return s[start: start + longest_len]