渣渣的Leetcode之旅(Python3)_5.最长回文子串(中等)

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

示例 1:
输入:s = “babad”
输出:“bab”
解释:“aba” 同样是符合题意的答案。

示例 2:

输入:s = “cbbd” 输出:“bb”

示例 3:

输入:s = “a” 输出:“a”

示例 4:

输入:s = “ac” 输出:“a”

提示:

1 <= s.length <= 1000
s 仅由数字和英文字母(大写和/或小写)组成

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/longest-palindromic-substring
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

首先最基础的想法是暴力,找出所有的字串然后判断是不是回文,但这样时间耗费很大。
然后进一步的想法是动态规划,如下:
长度为4,只要最中间的两个位置是回文,首位和末位的字符相等,那么这个4位子串就是回文
长度为5,只要最中间的三个位置是回文,首位和末位的字符相等,那么这个5位子串就是回文
长度为6,只要最中间的四个位置是回文,首位和末位的字符相等,那么这个6位子串就是回文
依此类推。。。
在这里插入图片描述

由此我们可以找出所有子串中的回文串,然后将结果保存在二位数组中,但这样遇到极长的串时会超时

class Solution:
    def longestPalindrome(self, s: str) -> str:
        if len(s) == 0 or len(s) == 1:
            return s
        array = [[0]*len(s) for i in range(len(s))]
        num = 0
        for i in range(2,len(s)+1):
            for j in range(len(s)-1):
                if i+j > len(s):
                    break
                if i == 2:
                    if s[j] == s[j+1]:
                        array[j][j+1] = 1
                        num = 2
                        continue
                if i == 3:
                    if s[j] == s[j+2]:
                        array[j][j+2] = 1
                        num = 3
                        continue
                if s[j] == s[i+j-1] and array[j+1][i+j-2] == 1:
                    array[j][i+j-1] = 1
                    if num < i:
                        num = i
        str_a = ""
        if num == 0:          
            str_a = str_a + s[0]
            return str_a            
        else:
            fin = 0
            for i in range(len(s)+100):
                if array[i][i+num-1] == 1:
                    fin = i
                    break
            for i in range(fin,fin+num):
                str_a = str_a + s[i]
            return str_a

 

在这里插入图片描述

优化一下:
由最基础的长度为2以及长度为3的回文串向外扩展

在这里插入图片描述
如果得到的长度为4或者为5的子串也是回文串,那就继续向外扩展至长度为6或者7,不断重复,直到不为回文串为止
在这里插入图片描述

如果得到的长度为4或者为5的子串不是回文串,那就找到下一组长度为2或者3的回文串向外扩展
通过向外扩展找回文串的方法,找到长度最长的回文串,输出即可

class Solution:
    def longestPalindrome(self, s: str) -> str:
        if len(s) == 0 or len(s) == 1:
            return s
        array = [[0]*len(s) for i in range(len(s))]
        num = 0
        fin_sta = 0
        sta = 0
        middle_num = 0
        three_num = 0
        for i in range(2,4):  #这两个for循环用来找到所有长度为2和3的回文子串
            for j in range(len(s)-1):
                if i+j > len(s):
                    break
                if s[j] == s[j+i-1]:
                    array[j][j+i-1] = 1
                    num = i
                    continue 
        for i in range(len(s)-2):
            middle_num = 2
            three_num = 3
            if array[i][i+1] == 1:
                low = i 
                high = i + 1
                while True:
                    low = low - 1
                    high = high + 1
                    if low <0 or high > len(s)-1 or s[low] != s[high]:
                        break
                    if s[low] == s[high]:
                        middle_num += 2
                        sta = low
                if num < middle_num:
                    num = middle_num
                    fin_sta = sta
            if array[i][i+2] == 1:
                low = i
                high = i + 2
                while True:
                    low = low - 1
                    high = high + 1
                    if low < 0 or high > len(s)-1 or s[low] != s[high]:
                        break
                    if s[low] == s[high]:
                        three_num += 2
                        sta = low
                if num < three_num:
                    num = three_num
                    fin_sta = sta     

        str_a = ""
        if num == 0:          
            str_a = str_a + s[0]
            return str_a   
        if num == 2:
            for i in range(len(s)-1):
                if s[i] == s[i+1]:
                    str_a = str_a + s[i] + s[i+1]
                    break
            return str_a
        if num == 3:
            for i in range(len(s)-1):
                if s[i] == s[i+2]:
                    str_a = str_a +s[i] + s[i+1] + s[i+2]
                    break
            return str_a
        for i in range(fin_sta,fin_sta + num ):
            str_a = str_a + s[i]
        return str_a

 

在这里插入图片描述

posted @ 2021-02-20 09:19  336699强强  阅读(96)  评论(0编辑  收藏  举报