【算法训练】LeetCode#5 最长回文子串

一、描述

最长回文子串

给你一个字符串 s,找到 s 中最长的回文子串。

输入:s = "babad"
输出:"bab"
解释:"aba" 同样是符合题意的答案。

示例 2:

输入:s = "cbbd"
输出:"bb"

二、思路

  • 中心扩散,从第一位开始,遵从左右左的方式扩散
  • 扩散时将做过判断的字符串放入备选数组,防止重复判断
  • 当得到回文子串时,记录长度,下次扩散直接从等长开始

三、解题

中心扩散,只能通过50%,输入样例为下面这个时,会超时(本地运行为0.4秒)

kyyrjtdplseovzwjkykrjwhxquwxsfsorjiumvxjhjmgeueafubtonhlerrgsgohfosqssmizcuqryqomsipovhhodpfyudtusjhonlqabhxfahfcjqxyckycstcqwxvicwkjeuboerkmjshfgiglceycmycadpnvoeaurqatesivajoqdilynbcihnidbizwkuaoegmytopzdmvvoewvhebqzskseeubnretjgnmyjwwgcooytfojeuzcuyhsznbcaiqpwcyusyyywqmmvqzvvceylnuwcbxybhqpvjumzomnabrjgcfaabqmiotlfojnyuolostmtacbwmwlqdfkbfikusuqtupdwdrjwqmuudbcvtpieiwteqbeyfyqejglmxofdjksqmzeugwvuniaxdrunyunnqpbnfbgqemvamaxuhjbyzqmhalrprhnindrkbopwbwsjeqrmyqipnqvjqzpjalqyfvaavyhytetllzupxjwozdfpmjhjlrnitnjgapzrakcqahaqetwllaaiadalmxgvpawqpgecojxfvcgxsbrldktufdrogkogbltcezflyctklpqrjymqzyzmtlssnavzcquytcskcnjzzrytsvawkavzboncxlhqfiofuohehaygxidxsofhmhzygklliovnwqbwwiiyarxtoihvjkdrzqsnmhdtdlpckuayhtfyirnhkrhbrwkdymjrjklonyggqnxhfvtkqxoicakzsxmgczpwhpkzcntkcwhkdkxvfnjbvjjoumczjyvdgkfukfuldolqnauvoyhoheoqvpwoisniv
from sys import flags
from typing import List

class Solution:
    inputS = ""
    overS = []
    maxSum = 0
    maxStr = ""
    sLen = 0
    def longestPalindrome(self, s: str) -> str:
        self.inputS = s
        self.sLen = len(s)
        for i in range(self.sLen):
            self.getCurrent(i)
        if self.sLen == 1 or self.maxSum == 0:
            return s[0]
        return self.maxStr

    def getCurrent(self,currentLoc):
        # 获取当前位置左右扩展字符串,通过调用judHui判断回文
        flags = False
        leftLoc = currentLoc
        rightLoc = currentLoc
        while True:
            if flags:
                rightLoc += 1
            else:
                leftLoc -= 1
            
            flags = not flags

            if leftLoc < 0 or rightLoc > self.sLen -1:
                break

            if rightLoc - leftLoc + 1 < self.maxSum:
                # 长度小于最大长度就不做判断
                continue
            
            self.judHui(leftLoc,rightLoc)


    def judHui(self,leftLoc,rightLoc):
        tempLeft = leftLoc
        tempRight = rightLoc
        # 通过左右坐标判断当前字符串是否为回文字符串
        while rightLoc >= leftLoc:
            if self.inputS[rightLoc] != self.inputS[leftLoc]:
                self.overS.append(self.inputS[tempLeft:tempRight+1]) # 判断过的不再判断
                return 
            rightLoc -= 1
            leftLoc += 1
        else:
            # 是回文
            if tempRight - tempLeft + 1 > self.maxSum:
                self.maxSum = tempRight - tempLeft + 1
                self.maxStr = self.inputS[tempLeft:tempRight+1]
                self.overS.append(self.inputS[tempLeft:tempRight+1]) # 判断过的不再判断
                return 
 

上面这种写法有太多重复性判断了,导致超时....


class Solution:
    inputS = ""
    maxSum = 0
    maxStr = ""
    sLen = 0
    def longestPalindrome(self, s: str) -> str:
        self.inputS = s
        self.sLen = len(s)
        if self.sLen == 1:
            return s[0]
        if self.sLen == 2:
            if s[0] == s[1]:
                return s
            else:
                return s[0]
        for i in range(self.sLen):
            self.getCurrent(i)
        if self.maxSum == 0:
            return s[0]
        return self.maxStr

    def getCurrent(self,currentLoc):
        # 获取当前位置左右扩展字符串,通过调用judHui判断回文
        leftLoc,rightLoc = currentLoc,currentLoc
        curLen = 1
        # 先找到当前位置左右相同的界限,将界限作为起始扩散位置
        while True:
            while leftLoc > 0 and self.inputS[leftLoc-1] == self.inputS[currentLoc]:
                curLen += 1
                leftLoc -= 1
            while rightLoc < self.sLen - 1 and self.inputS[rightLoc+1] == self.inputS[currentLoc]:
                curLen += 1
                rightLoc += 1
            if curLen > self.maxSum:
                self.maxSum = curLen
                self.maxStr = self.inputS[leftLoc:rightLoc+1]
            break
        while True:
            leftLoc -= 1
            rightLoc += 1
            
            if leftLoc < 0 or rightLoc > self.sLen - 1:
                break

            if self.inputS[rightLoc] != self.inputS[leftLoc]:
                return 
            else:
                curLen += 2
                if curLen > self.maxSum:
                    self.maxSum = curLen
                    self.maxStr = self.inputS[leftLoc:rightLoc+1]
posted @ 2022-11-23 13:40  小拳头呀  阅读(2)  评论(0编辑  收藏  举报