第一节
最长回文子串
给出一个字符串(假设长度最长为1000),求出它的最长回文子串,你可以假定只有一个满足条件的最长回文串。
样例
给出字符串 "abcdzdcab"
,它的最长回文子串为 "cdzdc"
。
挑战
O(n2) 时间复杂度的算法是可以接受的,如果你能用 O(n) 的算法那自然更好。
我的n^3代码:
class Solution:
"""
@param s: input string
@return: the longest palindromic substring
"""
def longestPalindrome(self, s):
# write your code here
start, end = 0, 0
for i in range(0, len(s)):
for j in range(i, len(s)):
if (j-i)>(end-start) and self.isPalind(s, i, j):
start, end = i, j
return s[start:end+1]
def isPalind(self, s, i, j):
while i<j:
if s[i] != s[j]:
return False
i += 1
j -= 1
return True
从中心点左右遍历的解法,注意回文是奇偶情况,这才是这个题目的关键点:
class Solution:
"""
@param s: input string
@return: the longest palindromic substring
"""
def longestPalindrome(self, s):
# write your code here
start,end = 0,0
n = len(s)
def locatePalindrome(s, i, j):
nonlocal start,end
while i>=0 and j<n:
if s[i] == s[j]:
if end-start < j-i+1:
start,end = i,j+1
else:
break
i -= 1
j += 1
for i in range(n):
# center i
locatePalindrome(s, i, i)
# center i,i+1
locatePalindrome(s, i, i+1)
return s[start:end]
DP解法:细节有点多,不一定能够写对。。。尤其是那个for是从大到小递减。
class Solution:
"""
@param s: input string
@return: the longest palindromic substring
"""
def longestPalindrome(self, s):
# write your code here
start = end = 0
n = len(s)
dp = [[False]*n for _ in range(n)]
for i in range(n-1, -1, -1): # for i in range(0, n) WRONG!!!!
for j in range(i, n):
if i == j:
dp[i][j] = True
else:
dp[i][j] = (s[i] == s[j]) and (j==i+1 or dp[i+1][j-1])
if dp[i][j] and (j-i+1) > (end-start):
start, end = i, j+1
return s[start:end]
Why is it not working if outside loop use for (int i = 0; i < n; i++)?
因为推导公式里 i 依赖于 i+1,所以i+1要比 i 先算出来,所以要倒过来循环。