力扣第5题 最长回文串

最长回文串
leetcode m005

1、滑窗

受M003启发,用了Sliding Window 结果超时了。。。。用Pycharm能跑出结果,代码如下:

def M005(s: str) -> str:
    n = len(s)
    if n == 1:
        return s
    ans = s[0]
    for i in range(n):
        rk = i
        temp = s[i]
        while rk+1 < n:
            temp = temp+s[rk+1]
            if temp == temp[::-1]:
                ans = ans if len(ans) > len(temp) else temp
            rk += 1
    return ans

2、中心扩展

这个解法很好想到,从头遍历字符串,以每一个遍历到的字符串为中心向两周扩展,找到最大的。但是这个解法有个问题:

  • 对于ssdss,当遍历到d的时候能找到最长的ssdss
  • 对于ssddss就不行,这时最长的只是ss或dd

这是因为以单个字母为中心只对单数个回文字符串有效,对偶数个会出问题。对于这个问题官方的解决办法很有意思,当遍历到每一个字母时,本来是以这个字母为中心向两边扩展,这时再加一个以这个字母和下一个字母这两个字母为中心同时扩展,取较大的那个
代码如下:

def M005(s: str) -> str:
    n = len(s)
    if n == 1:
        return s
    # 从第num个开始向两侧走找到最多的回文并返回
    # 注意调用的时候有两次,一次初始状态left=right 一次right=left+1
    # 这样就将我苦苦思索的单双问题给解决了!!

    def expandAroundCenter(left, right):
        while left >= 0 and right < n and s[left] == s[right]:
            left -= 1
            right += 1
        return left+1, right-1

    def help():
        start = end = 0
        for i in range(n):
        # 注意这里,调用了两次扩展
            left1, right1 = expandAroundCenter(i, i)
            left2, right2 = expandAroundCenter(i, i+1)
            if right1-left1 > end - start:
                start, end = left1, right1
            if right2 - left2 > end - start:
                start, end = left2, right2
        return s[start: end+1]
    return help()

你可能感兴趣的:(算法相关,leetcode,算法,职场和发展)