LeetCode[003]

LeetCode: 最长回文子串

题目:

给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。

示例 1:

输入: “babad”
输出: “bab”
注意: “aba” 也是一个有效答案。

初步尝试:暴力解法

基本思路:

  1. 全部循环得到所有可能的回文子串并储存。
  2. 判断最长的回文后输出

这道题我完全不知道怎么下手,参考原文地址

class Solution:
    def longestPalindrome(self, s):
        # 如果字符串长度为1,直接返回原字符串
        len_s = len(s)
        if len_s == 1:
            return s
        # 新建空的字符串保存回文,新建一个空的列表保存所有可能的回文子串
        substring = ''
        substring_set = []
        for i in range(len_s):
            for j in range(len_s):
                if i < j:
                    substring = s[i:j+1]
                    if self.is_Palindrome(substring) == 1:
                        substring_set.append(substring)
        longestP = ''
        if substring_set:
            longestP = substring_set[0]
        else:
            return s[0]
        # 判断最长回文子串
        for i in range(len(substring_set)):
            if len(longestP) < len(substring_set[i]):
                longestP = substring_set[i]
        return longestP
        
    # 判断是否为回文字串
    def is_Palindrome(self, t):
        len_t = len(t)
        for i in range(len_t):
            if not t[i] == t[len_t - 1 - i]:
                return 0
        return 1
    
s = Solution()
s.longestPalindrome('babad')

这样做的缺点很明显,就是会浪费很多的时间。

思路二:“马拉车”算法 Manacher’s Algorithm

  1. 插入 #,使得字符串变为奇数
  2. 寻找回文最大右半径

举个例子:s=“abbahopxpo”,转换为s_new="$#a#b#b#a#h#o#p#x#p#o#"

i0123456789101112131415161718192021
s_new[i]$#a#b#b#a#h#o#p#x#p#o#
p[i]121452121212121612121

原文地址:https://blog.csdn.net/qq_39241986/article/details/82927399

这个对于我来讲还是太难了

class Solution:
	def longestPalindrome(self, s):
		"""
		:type s: str
		:rtype: str
		"""
		t0 = '#'.join(s)
		s_new = '#' + t0 + '#'
		len_new = []
		sub = '' # 最长回文字符串
		sub_midd = 0  # 表示在i之前所得到的Len数组中的最大值所在位置
		sub_side = 0  # 表示以sub_midd为中心的最长回文子串的最右端在S_new中的位置
		for i in range(len(s_new)):
			if i < sub_side :
				# i < sub_side时,在Len[j]和sub_side - i中取最小值,省去了j的判断
				j = 2 * sub_midd - i
				if j >= 2 * sub_midd - sub_side and  len_new[j] <= sub_side - i:
					len_new.append(len_new[j])
				else:
					len_new.append(sub_side - i + 1)
			else:
				# i >= sub_side时,从头开始匹配
				len_new.append(1)
			while ((i - len_new[i] >= 0 and i + len_new[i] < len(s_new)) and (s_new[i - len_new[i]] == s_new[i + len_new[i]])):
				# s_new[i]两端开始扩展匹配,直到匹配失败时停止
				len_new[i] = len_new[i] + 1
				
			if len_new[i] >= len_new[sub_midd]:
				sub_side = len_new[i] + i - 1
				sub_midd = i
		a0 = int((2 * sub_midd - sub_side)/2)
		b0 = int(sub_side / 2)
		sub = s[a0 :b0 ] # 在s中找到最长回文子串的位置
		return sub

还有一个办法是从中间入手,向两边拓展,分奇偶讨论,这里就不放出来了。

其他参考资料:

如何找到字符串中的最长回文子串
Longest Palindromic Substring Part II
马拉车算法

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值