5. 最长回文子串 中心扩散法

给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。
示例 1:
输入: "babad"
输出: "bab"
注意: "aba" 也是一个有效答案。
示例 2:
输入: "cbbd"
输出: "bb"

解题思路

解法一:双指针

class Solution:
    def longestPalindrome(self, s):
        left = 0
        right = 0
        n = len(s)
        p1 = p2 = ''
        # 双指针,遍历两遍
        while(right<n):
            # 当回文子串长度为奇数时,即只有1或3、5这种,
            # 比如当找到了回文长度为3的子串后,后面就只找长度大于3的子串了,下一个是5
            if left>-1 and s[left:right+1] == s[left:right+1][::-1]:
                p1 = s[left:right+1]
                # 当当前子串是回文时,增加下一个要找的子串的长度
                right += 1
                left -= 1      
            else:
                right += 1
                left += 1
                
        left = 0
        right = 1
        while(right<n):
            # 当回文子串长度为偶数时
            if left>-1 and s[left:right+1] == s[left:right+1][::-1]:
                p2 = s[left:right+1]
                right += 1
                left -= 1   
            else:
                right += 1
                left += 1
                
        return p1 if len(p1)>len(p2) else p2

解法二

还是双指针,在每个字母之间插入特殊字符‘#’,使得只需要遍历一次

class Solution:
    def longestPalindrome(self, s):
        # 双指针解法
        length = len(s)
        if length==1:
            return s 
        A = '#' + '#'.join(s) + '#'
        max_len = 0 
        ret_str = ''
        left = 0
        right = 0 
        while right < len(A):
        	# 之后的长度要大于之前记录的最大长度才进行更新           
            if left > -1 and max_len<(right+1-left) and A[left:right + 1]==A[left:right + 1][::-1]:
                max_len = right + 1 - left
                ret_str = A[left:right + 1]

                right += 1
                left -= 1 
            else:
                right += 1
                left += 1
        # 返回时删除‘#’
        return ret_str.replace('#', '')
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值