classSolution(object): deflongestPalindrome(self, s): """ :type s: str :rtype: str """ n = len(s) bl = [[0for i in range(n)]for i in range(n)] start = 0 end = n for leng in range(1,n+1): for i in range(n-leng+1): if leng == 1: bl[i][i] = 1 start = i end = i + leng continue if (leng == 2) & (s[i] == s[i + 1]): bl[i][i + 1] = 1 start = i end = i + leng continue if (bl[i+1][i+leng-2] == 1) & (s[i] == s[i+leng-1]): bl[i][i+leng-1] = 1 start = i end = i + leng return s[start:end]
classSolution(object): defgetstr(self,s,left,right): while left - 1 >= 0and right < len(s): if s[left - 1] != s[right]: break left -= 1 right += 1 return s[left:right] deflongestPalindrome(self, s): """ :type s: str :rtype: str """ result = '' n = len(s) for i in range(n): l = self.getstr(s,i,i+1) if len(l) >= len(result): result = l if i != n-1and s[i] == s[i+1] : l = self.getstr(s,i,i+2) if len(l) >= len(result): result = l return result
char * longestPalindrome(char * s){ int n = strlen(s), start = 0, end = 0; for(int i = 0; i < n; i++){ //奇数 int left = i - 1, right = i + 1; while(left >= 0 && right < n && s[left] == s[right]){ left--; right++; } if(right - left - 1 > end - start){ start = left + 1; end = right; } } for(int i = 0; i < n - 1; i++){ //偶数 if(s[i] == s[i + 1]){ int left = i - 1, right = i + 2; while(left >= 0 && right < n && s[left] == s[right]){ left--; right++; } if(right - left - 1 > end - start){ start = left + 1; end = right; } } } s[end] = '\0'; return &s[start]; }
解析:
无论是动态规划法还是中心扩散法,理论上他们的时间复杂度都应该是O(n^2)。
关于动态规划:
是有一个二维布尔数组bool_list[i][j],若值为1,则表示字符串中 i 位到 j 位构成回文子串。
动态规划中首先遍历长度leng,每次再遍历字符串,观察是否具有长度为leng的回文子串。
1 2
for(int len = 1 ; len <= n ; len++) //leng从1开始 for(int i = 0 ; i <= n -len ; i++) //每次遍历到字符串的n-leng位
其中boollist[i][j],若i = j,则恒为1,因为字符串始终具有长度为1的回文子串。
1 2 3 4 5 6
if(len == 1){ token[i][i] = 1; start = i; end = i + 1; continue; }
for(int i = 0; i < n; i++){ //奇数 int left = i - 1, right = i + 1; while(left >= 0 && right < n && s[left] == s[right]){ left--; right++; } if(right - left - 1 > end - start){ start = left + 1; end = right; } }
for(int i = 0; i < n - 1; i++){ //偶数 if(s[i] == s[i + 1]){ int left = i - 1, right = i + 2; while(left >= 0 && right < n && s[left] == s[right]){ left--; right++; } if(right - left - 1 > end - start){ start = left + 1; end = right; } } }