python----最长回文子串的暴力解法以及动态规划解法

第一种:暴力解法,双重循环,o(n^2)

def longestPalindString(ss):
    palindString=""
    max_len=0
    if len(ss)==1:
        return ss
    for i in range(len(ss)):
        for j in range(i+1,len(ss)):
            is_palind=True
            for k in range(i,int((i+j)//2)+1):
                if ss[k]!=ss[j-k+i]:
                    is_palind=False
                    break
            if is_palind and (j-i+1)>max_len:
                max_len=j-i+1
                palindString=ss[i:j+1]
    if palindString=="":
        palindString=ss[0]
    return palindString

if __name__=="__main__":
    ss="babcbad"
    print(longestPalindString(ss))

第二种:动态规划解法,时间复杂度o(n^2)
, 空间复杂度o(n^2)
首先是求最优问题,首先想到动态规划三要素:最优子结构、边界、状态转移方程
其中,
状态转移方程:f(i,j):s[i]==s[j] i-j<=1
f(i,j):s[i]==s[j] and f(i+1,j-1) j-i>1
其中:f(i,j)表示s[i:j+1]是否回文串

def longestPalindString(s):
    k=len(s)
    matrix=[[0 for i in range(k)] for j in range(k)]
    longestString=""
    longestLen=0
    for j in range(0,k):
        for i in range(0,j+1):
            if j-i<=1:
                if s[i]==s[j]:
                    matrix[i][j]=1
                    if longestLen<j-i+1:
                        longestString=s[i:j+1]
                        longestLen=j-i+1
            else:
                if s[j]==s[i] and matrix[i+1][j-1]:
                    matrix[i][j]=1
                    if longestLen<j-i+1:
                        longestString=s[i:j+1]
                        longestLen=j-i+1
    return longestString

if __name__=="__main__":
    ss="babcbad"
    print(longestPalindString(ss))

第三种方法:动态规划算法的优化
时间复杂度不变,将空间复杂度降低为o(2n)
用nlist存储j情况下所有的子串是否为回文子串的标志
用olist存储j-1情况下所有的子串是否为回文子串的标志

def longestPalindString(s):
    k = len(s)
    olist = [0] * k  # 申请长度为n的列表,并初始化
    nList = [0] * k  # 同上
    logestSubStr = ""
    logestLen = 0
    for j in range(0, k):
        for i in range(0, j + 1):
            if j - i <= 1:
                if s[i] == s[j]:
                    nList[i] = 1  # 当 j 时,第 i 个子串为回文子串
                    len_t = j - i + 1
                    if logestLen < len_t:  # 判断长度
                        logestSubStr = s[i:j + 1]
                        logestLen = len_t
            else:
                if s[i] == s[j] and olist[i + 1]:  # 当j-i>1时,判断s[i]是否等于s[j],并判断当j-1时,第i+1个子串是否为回文子串
                    nList[i] = 1  # 当 j 时,第 i 个子串为回文子串
                    len_t = j - i + 1
                    if logestLen < len_t:
                        logestSubStr = s[i:j + 1]
                        logestLen = len_t
        olist = nList  # 覆盖旧的列表
        nList = [0] * k  # 新的列表清空
    return logestSubStr

if __name__=="__main__":
    ss="babcbad"
    print(longestPalindString(ss))

第四种解法:

def helper(ss,l,r):
    while l>=0 and r<len(ss) and ss[l]==ss[r]:
        l=l-1
        r=r+1
    return ss[l+1:r]

def longgestCommonStr(ss):
    res=""
    for i in range(len(ss)):
        temp=helper(ss,i,i)
        if len(temp)>len(res):
            res=temp
        temp=helper(ss,i,i+1)
        if len(temp)>len(res):
            res=temp
    return res
if __name__=="__main__":
    ss="abddbc"
    result=longgestCommonStr(ss)
    print(result)

猜你喜欢

转载自blog.csdn.net/haoshan4783/article/details/88714499
今日推荐