[leetcode] 5.Longest Palindromic Substring-2
想了很多方法 搞轴对称,算对称轴,偶数都搞出了一堆0.5在那加加减减,最后发现在移轴之前可能就返回了。
class Solution: def longestPalindrome(self, s: str) -> str: # longest palindromic substring lenth < 1000 # NULL lengthS = len(s) if lengthS == 0: return '' # --- # regular # a not empty string must have 1 letterd palindromic substring:string[0] longestPalindSubStringLength = 1 longestPalindSubString = s[0] if lengthS == 1: return longestPalindSubString #for any string,the longest palindoromic subtring is when the axis in the middle if lengthS %2 == 1: #even axis = lengthS // 2 offset = [0] for i in range(1, axis): offset.append(i) offset.append(-i) for index in range(len(offset)): # move axis[0,+1,-1,+2,-2...] currentaxis = axis + offset[index] for decrease in range(0, currentaxis): if (lengthS // 2 - currentaxis) > 0: # axis at leftside tempstr = s[decrease:2 * currentaxis - decrease] tempstrlength = len(tempstr) if tempstrlength < 2 or tempstrlength <longestPalindSubStringLength: continue if (self.isPalind(tempstr)): if tempstrlength > longestPalindSubStringLength: longestPalindSubString = tempstr else: # axis at rightside middle tempstr = s[currentaxis - ((lengthS-1-decrease) - currentaxis):lengthS - decrease] tempstrlength = len(tempstr) if tempstrlength < 2 or tempstrlength <longestPalindSubStringLength: continue if (self.isPalind(tempstr)): if tempstrlength > longestPalindSubStringLength: longestPalindSubString = tempstr else: #odd #--- #self middle have no axis in int. have to check first axis = lengthS / 2 -0.5 #2.5 offset = [] if axis >1: for i in range(1, int(axis + 0.5)): offset.append(i - 0.5) offset.append(-(i - 0.5)) for index in range(len(offset)): # move axis[0,+0.5,-0.5,+1.5,-1.5...] currentaxis = int(axis + offset[index]) for decrease in range(0, currentaxis): if (lengthS // 2 - currentaxis) > 0: # axis at leftside tempstr = s[decrease:2 * currentaxis - decrease] tempstrlength = len(tempstr) if tempstrlength < 2 or tempstrlength <longestPalindSubStringLength: continue if (self.isPalind(tempstr)): if tempstrlength > longestPalindSubStringLength: longestPalindSubString = tempstr else: # axis at rightside tempstr = s[currentaxis - ((lengthS-1-decrease) - currentaxis):lengthS - decrease] tempstrlength = len(tempstr) if tempstrlength < 2 or tempstrlength < longestPalindSubStringLength: continue if (self.isPalind(tempstr)): if tempstrlength > longestPalindSubStringLength: longestPalindSubString = tempstr return longestPalindSubString def isPalind(self, substring: str) -> bool: # notice substring >= 2 substringlength = len(substring) if (substringlength % 2) == 1: # odd temp1 = substring[0:substringlength // 2 + 1] temp2 = substring[substringlength:substringlength // 2 - 1:-1] if temp1 == temp2: return True else: return False else: # even temp1 = substring[0:substringlength // 2] temp2 = substring[substringlength:substringlength // 2 - 1:-1] if temp1 == temp2: return True else: return False
testcase101:
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabcaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
后来发现稍微做下优化 提前return就能达到时间限制。
103 / 103 test cases passed.
|
Status:
Accepted |
Runtime: 8876 ms
Memory Usage: 13.2 MB
|
Submitted: 4 minutes ago
|
class Solution: def longestPalindrome(self, s: str) -> str: # longest palindromic substring lenth < 1000 # NULL lengthS = len(s) if lengthS == 0: return '' #all same if lengthS == s.count(s[0]): return s # --- # regular # a not empty string must have 1 letterd palindromic substring:string[0] longestPalindSubStringLength = 1 longestPalindSubString = s[0] for start in range(lengthS): for end in range(start + 1, lengthS + 1): # [] operator is right open interval,will not count "end" if no +1 # left to right for end in range(start + 1, len(s) + 1) #from right to left range(length -1,-1) currentstring = s[start:end] currentstringLength = len(s[start:end]) # one letter if len(currentstring) == 1 or currentstringLength <= longestPalindSubStringLength: continue if (self.isPalind(currentstring)): if currentstringLength > longestPalindSubStringLength: if end == lengthS: return currentstring #speed up longestPalindSubStringLength = currentstringLength longestPalindSubString = currentstring return longestPalindSubString def isPalind(self, substring: str) -> bool: # notice substring >= 2 substringlength = len(substring) if (substringlength % 2) == 1: # odd temp1 = substring[0:substringlength // 2 + 1] temp2 = substring[substringlength:substringlength // 2 - 1:-1] if temp1 == temp2: return True else: return False else: # even temp1 = substring[0:substringlength // 2] temp2 = substring[substringlength:substringlength // 2 - 1:-1] if temp1 == temp2: return True else: return False
最后抄袭一个92ms的Manacher's Algorithm算法:
class Solution: def longestPalindrome(self, s: str) -> str: res = 0 p = "" for i in range(0, len(s)): # 1 for d in [0,1]: if s[i-res:i][::-1] == s[i+d:i+res+d]: j = res+1 while (i-j >= 0) and (i+j+d) <= len(s) and s[i-j] == s[i+j+d-1]: j += 1 if j > res+1 or d == 1: p = s[i-j+1:i+j+d-1] res = len(p) // 2 return p