算法培训
第一节
最长回文子串
给出一个字符串(假设长度最长为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 先算出来,所以要倒过来循环。