題目描述
動態規劃算法求解
解題思路1:
假設字符串s的長度爲len, 則先創建一個長度爲len * len的全0數組M,用來存放最大回文串的長度。
M[i][j]表示以下標i開始,j結束,則共有兩層循環,外層循環j的取值爲(0,len), 內層循環i的取值爲(0,j+1),有如下的狀態轉移方程:
當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的含義與前面一致,則狀態轉移方程變爲:
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]