尋找最長迴文字符串—python實現

 題目描述

動態規劃算法求解

解題思路1:

假設字符串s的長度爲len, 則先創建一個長度爲len * len的全0數組M,用來存放最大回文串的長度。

M[i][j]表示以下標i開始,j結束,則共有兩層循環,外層循環j的取值爲(0,len), 內層循環i的取值爲(0,j+1),有如下的狀態轉移方程:

\left\{\begin{matrix}i=j & M[i][j]=1 & \\ j-i = 1 \& s[i]=s[j] & M[i][j]=2 &\\ j-i >1 \& s[i]=s[j] \& M[i+1][j-1]>0 & M[i][j]=M[i+1][j-1] +2 &\\ j-i>1 \& s[i]=s[j] \& M[i+1][j-1]=0 & M[i][j]=0 \end{matrix}\right.

當i=j時,初始化數組M,即只有1個字符時,是迴文字符串。

下面均針對s[i]==s[j]的情況討論:

當j>i時 如果j與i只差1,則代表有兩個重複的字符,如bb, 也是迴文字符串,M[i][j]=2.

當j>1時,j-i>1, 則需比較其子字符串是否是迴文字符串(M[i+1][j-1]>0),若是,則設置M[i][j]的長度爲子迴文串長度+2,否則設置M[i][j]=0

參考代碼:

import numpy as np
class Solution(object):
    # 動態規劃 leetcode最後一個用例會超出時間限制
    def longestPalindrome(self, s):
        """
        :type s: str
        :rtype: str
        """
        if len(s) <=1:
            return s
        # 保存迴文長度的矩陣
        matrix = np.zeros((len(s),len(s)))
        max_len = 0
        # 動態規劃求解
        for j in range(0,len(s)):
            for i in range(0,j+1):
                if i == j:
                    matrix[i][j] = 1 # 僅有1個字符時
                else:
                    if s[i] == s[j]:
                        if j-i == 1:
                            matrix[i][j] = 2
                        elif matrix[i+1,j-1] > 0:
                            matrix[i][j] = matrix[i+1,j-1] + 2
                        else:
                            matrix[i][j] = 0
                    else:
                        matrix[i][j] = 0
        print(matrix)
        logest_len= int(np.max(matrix))
        # print(np.argmax())
        row = np.argmax(matrix)//len(s)
        col = np.argmax(matrix)%len(s)
        return s[row:row+logest_len]

解題思路2:

由於該方法計算了每個迴文字符串的長度,增加了運行時間,爲了減少時間,我們將M設置爲bool數組,用來保存是否爲迴文串的狀態。

i和j的含義與前面一致,則狀態轉移方程變爲:

\left\{\begin{matrix} if & s[i]=s[j] \& (j-i<2 or M[i+1][j-1]) & M[i][j]=True \\else & M[i][j]=False \end{matrix}\right.

if語句將前面公式的前三項糅合在一起了,只要滿足if的條件,則即爲迴文字符串。否則不是迴文字符串。

該方法注意保存最長迴文字符串的大小和最長迴文串的位置。

參考代碼:

import numpy as np
class Solution(object):
    # 修改後的動態規劃算法
    def longestPalindrome(self, s):
        """
        :type s: str
        :rtype: str
        """
        if len(s) <=1:
            return s
        # 保存狀態的矩陣
        matrix = np.zeros((len(s),len(s)),dtype=bool)
        max_len = 0 # 最長迴文字符串的大小
        loc = (0,0) # start,end 最長迴文串的位置
        # 動態規劃求解
        for j in range(0,len(s)):
            for i in range(0,j+1):
                if s[i]==s[j] and ( j-i<2 or matrix[i+1][j-1]):
                    matrix[i][j] = True
                    if max_len < j-i+1:
                        max_len = j-i+1 # 長度
                        loc = (i,j)  # 位置
        
        return s[loc[0]:loc[0]+max_len]
        

 

發佈了9 篇原創文章 · 獲贊 0 · 訪問量 8886
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章