Datawhale leetcode训练营 第三天

题目描述

在这里插入图片描述

方法一:

暴力循环法,找出所有的可能的字符串,再判断是否是回文。
啥比了很长一段时间没想明白,原来是因为s[i:k]的语法是表达s[i]~s[k-1]。
附上惨痛教训无处不print代码,方便像我一样的菜鸡理解。
应该解释的比较清楚了,大家用的时候把print去掉就行。

s = 'babad'
l = len(s)
print("l =",l)
max_length = 0
#将回文字符串定义为一个空字符串
palindromic_sequence = ''
 #如果待判定的字符串种只有一个字符,那它必定是回文字符串
if len(s) == 1:
    print(s)
#做一个循环,从第一个字符开始检查
for i in range(l):
    print("i =",i)
    #从第二个字符为末尾,第一个字符为开头形成字符串,也就是依次12,13,14,...,1l
    for j in range(i + 1, l):
        print("j =",j)
        #先假定这个字符串是回文
        is_palindromic = True
        #k是用来算检查字符串是否是回文的下标,k最大是int((i + j) / 2) + 1
        #这是因为如果检查的字符串的字符个数是偶数,由于字符串下标是从0开始的,所以要+1,刚好就是中间位置
        #如果是奇数=上一行的偶数+1,因为回文不收最中间的那个字符的影响,所以和偶数的情况一样,向下取整即可
        for k in range(i, int((i + j) / 2) + 1):
            print("k =",k)
            print(s[k],s[j-k+i])
            if s[k] != s[j - k + i]:
                print(s[k],s[j-k+i])
                is_palindromic = False
                #不符合条件就退出
                break
                #(j - i + 1) > max_length是避免空字符
            if is_palindromic and (j - i + 1) > max_length:
                #这是算回文字符长度
                max_length = j - i + 1
                palindromic_sequence = s[i:j + 1]
                #j+1的原因是s[i:k]的语法是s[i]~s[k-1]
                print("palindromic_sequence =",palindromic_sequence)
if palindromic_sequence == '':
    palindromic_sequence = s[0]
print(palindromic_sequence)

顺便附上实现的结果。
在这里插入图片描述
在这里插入图片描述

方法二:

中心枚举法,枚举字符串的中点,而不是从头开始循环。认真看注释啊,写了好久的,应该能看懂的。

class Solution:
    def longestPalindrome(self, s):
        """
        :type s: str
        :rtype: str
        """
        l = len(s)
        max_length = 0
        palindromic_sequence = ''
        for i in range(l):
        	#这里分间隔interval为1和0是要区分两种字符个数为奇数或者偶数的回文序列
        	#interval = 1是奇数的情况,也就是开始循环的这个字符现在是回文字符的中心
        	#它的左右两边要对称543212345,类似这种情况,1在中间。
            interval = 1
            while (i - interval) >= 0 and (i + interval) < l:
            	#上下界不能出
            	#保证中心左右两边对称
                if s[i + interval] == s[i - interval]:
                #保证中心左右两边对称
                    interval += 1
                else:
                    break
            interval -= 1
            #算长度时要减一,因为你成功对称一次就加了1,而你interval的起始值是1不是0,故要-1
            #2 *interval + 1是因为加上中心点的值的位置
            if 2 *interval + 1 > max_length:
                max_length = 2 *interval + 1
                palindromic_sequence = s[i - interval:i +interval + 1]
           interval = 0
           #interval = 0是回文字符串字符个数为偶数的情况
           #偶数的情况就是至少2个字符,所以interval = 0,最中间相邻的两个要相同
           #比如32100123这样
            if (i + 1) < l:
            #这一步是防止它是单字符串
                while (i - interval) >= 0 and (i + 1 + interval) < l:
                #上下界不能出
                    if s[i + 1 + interval] == s[i - interval]:
                    #保证两个中心两边相等,之后就是保证中心左右两边对称
                        interval += 1
                    else:
                        break
            interval -= 1
            #和奇数的时候同理,但是由于中心的个数变成两个了,所以是+2
            if 2 *interval + 2 > max_length:
                max_length = 2 *interval + 2
                palindromic_sequence = s[i - interval:i + interval + 2]
        if palindromic_sequence == '':
        #这里是单字符串的情况
            palindromic_sequence = s[0]
        return palindromic_sequence

方法三:

马拉车(manacher)算法
实在是没看懂代码,算法大致理解,先埋个坑五点交作业把链接附上。
稍微看懂了一点回来补充了,附上带print的代码。
具体讲解可以看第一条的链接

# manacher算法
class Solution:
    def longestPalindrome(self, s):
        """
        :type s: str
        :rtype: str
        """
        #预处理
        t='#'+'#'.join(s)+'#'
        print(t)

        RL=[0]*len(t)
        #生成和t一样长度的全为0的list
        print(RL)
        MaxRight=0
        print("MaxRight =",MaxRight)
        pos=0
        print("pos =",pos)
        # MaxLen=0
        for i in range(len(t)):
            print("i =",i)
            if i<MaxRight:
                print("MaxRight =",MaxRight)
                # 或者RL[i]=min(RL[2*pos-i], MaxRight-i)
                # 上述注释掉的这行代码直接等价于下面5行代码
                j=2*pos-i
                #j是i关于pos的对称点
                print("j =",j)
                if MaxRight-i>RL[j]:
                    RL[i]=RL[j]
                    print("RL =",RL)
                else:
                    RL[i]=MaxRight-i
                    print("RL =",RL)
            else:
                RL[i]=1
                print("RL =",RL)
            #尝试扩展,注意处理边界
            while i-RL[i]>=0 and i+RL[i]<len(t) and t[i-RL[i]]==t[i+RL[i]]:
                RL[i]+=1
                print("RL =",RL)
            #更新MaxRight,pos
            if RL[i] >= RL[pos]:
                MaxRight = RL[i] + i - 1
                print("MaxRight =",MaxRight)
                pos = i
                print("pos =",pos)
            '''
                if RL[i]+i-1>MaxRight:
                    MaxRight=RL[i]+i-1
                    pos=i
                #更新最长回文串的长度
                MaxLen=max(MaxLen, RL[i])
            return MaxLen-1
            '''
        a=int((2*pos-MaxRight)/2)
        print("a =",a)
        b=int(MaxRight/2)
        print("b =",b)
        return s[a:b]
s = Solution()
a = s.longestPalindrome('abab')
print(a)

https://mp.weixin.qq.com/s/D72qugTLpgITU6IJ1QQERg
https://www.felix021.com/blog/read.php?2040
https://www.bilibili.com/video/av4829276?from=search&seid=8243409683193841648

猜你喜欢

转载自blog.csdn.net/qq_35547281/article/details/86690418