time: 20190830
給定乙個字串 s,找到 s 中最長的回文子串。你可以假設 s 的最大長度為 1000。
示例 1:
輸入: 「babad」
輸出: 「bab」
注意: 「aba」 也是乙個有效答案。
示例 2:
輸入: 「cbbd」
輸出: 「bb」
在思路這部分,我們需要想清楚如何進入到動態規劃這種思路中來。
子串表示字串是連續的,那麼單個字元一定是回文的,在它的基礎上,左右兩邊擴充,如果左右兩邊字元相同,則新的字串也是回文的。這個思想可以繼續延續,即子問題不斷蔓延。狀態遷移方程逐漸變得清晰,以i
表示字串的起始,以j
表示字串的結束,則dp[i][j] = dp[i+1][j-1] and s[i] == s[j]
。
這時候再想明白如何更新動態陣列即可,顯然這裡用的是二維陣列來表示。第一維表示字串的起始下標,第二維表示結束下標。
最外層的主迴圈是字串的結束下標。
演算法一:暴力搜尋
class
solution
:def
longestpalindrome
(self, s:
str)
->
str:
defispalindrome
(st)
: size =
len(st)
for i in
range
(int
(size /2)
):if st[i]
!= st[size - i -1]
:return
false
return
true
max_length =-1
left, right =0,
0for i in
range
(len
(s))
:for j in
range
(i,len
(s))
:if ispalindrome(s[i:j +1]
)and j - i +
1> max_length:
max_length = j - i +
1 left = i
right = j
return s[left:right +
1]
這是不能ac的演算法,時間複雜度為o(n^3)
,只能幫助理解思路,不能作為最終的解法。
能ac的演算法是動態規劃型別,因此本題考查的要點是對動態規劃的理解。
演算法二:動態規劃,二維dp
class
solution
:def
longestpalindrome
(self, s:
str)
->
str:
# 初始化二維dp陣列,第一維表示從字串起始位置,第二維表示字串結束位置
# dp[i][j]表示以i開頭,j結束的字串是否為回文字串
dp =[[
false]*
len(s)
for _ in
range
(len
(s))
]
max_length =
1 start =
0# 從末尾開始迴圈,需要注意動態陣列的更新方式
for j in
range
(len
(s))
:for i in
range
(j +1)
:# print("i, j: ", i, j)
if j - i <2:
dp[i]
[j]= s[i]
== s[j]
else
:# 狀態轉移方程
dp[i]
[j]= dp[i+1]
[j-1
]and s[i]
== s[j]
if dp[i]
[j]and
(j - i +1)
> max_length:
max_length = j - i +
1 start = i
return s[start:start+max_length]
end. LeetCode5最長回文子串
給定乙個字串s,找到s中最長的回文子串。你可以假設s長度最長為1000。示例 輸入 babad 輸出 bab 注意 aba 也是有效答案示例 輸入 cbbd 輸出 bb 動態規劃來做,每個回文字串的子字串也是回文字串,即string是回文字串那麼它的string.substring 1,lenth ...
LeetCode 5 最長回文子串
問題描述 給定乙個字串s,找到s中最長的回文子串。你可以假設s的最大長度為1000。示例 1 輸入 babad 輸出 bab 注意 aba 也是乙個有效答案。示例 2 輸入 cbbd 輸出 bb 解決方案 中心擴充套件演算法 事實上,只需使用恆定的空間,我們就可以在 o n 2 的時間內解決這個問題...
leetcode5 最長回文子串
遞推式 1 一般 s i 1 s j 1 and j i and j i len s i 1,j 1 2 初始化dp矩陣對角線的值為 true,相鄰兩個元素相等時dp i i 1 為true 初始化回文串起始位置和長度。def longestpalindrome s n len s if s ret...