[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
原文地址:https://www.cnblogs.com/alfredsun/p/10780461.html