給定乙個字串 s,找到 s 中最長的回文子串。你可以假設 s 的最大長度為 1000。
示例 1:
輸入: "babad"
輸出: "bab"
注意: "aba" 也是乙個有效答案。
示例 2:
輸入: "cbbd"
輸出: "bb"
回文就是倒著念正著念都一樣的,如aba
倒過來念還是aba
。
一看這道題目就想起了動態規劃。
對於子字串s[i][j]
,如果s[i]==s[j]
,那麼就看被ij包裹的裡面的內容是不是回文,這就構成了遞迴式。
t(i,j) = s[i]==s[j] and t(i+1,j-1)
有遞迴就得有邊界條件,如果i和j中間有乙個字元或者沒字元,那麼就僅當s[i]==s[j]
時就是回文啦,比如aba
,aa
。所以可以推出個條件:j-i<3
的時候,結果是true
然後我們使用動態規劃,需要構造乙個二維陣列t儲存字串是否是回文的狀態。
class solution:
def longestpalindrome(self,s: str) -> str:
size = len(s)
t = [[false for j in range(size)] for i in range(size)]
ml = 1
si = 0
for j in range(1,size):
for i in range(j):
if s[i] == s[j]:
if j - i < 3:
t[i][j] = true
else:
t[i][j] = t[i+1][j-1]
if t[i][j]:
cl = j - i + 1
if cl > ml:
ml = cl
si = i
return s[si:si+ml]
時間複雜度o(n2),空間複雜度o(n2)
此法時間複雜度也是o(n^2),只是空間複雜度變成了常數級別。
思路是對於字串中的每乙個字元,認為它是回文串的中心,那麼只需查詢兩邊的一樣字串的長度就可以確定以它為中心的回文串的長度。然後去找最大的乙個。
class solution:
def longestpalindrome(self,s: str)->str:
start,length = 0 ,0
for i in range(len(s)):
curlen = max(
self.getpalindromelen(s,i,i),
self.getpalindromelen(s,i,i+1)
)
if curlen > length:
start = i - (curlen-1) // 2
length = curlen
return s[start:start+length]
def getpalindromelen(self,s: str,l:int,r:int)->int:
while l>=0 and r需要注意的就是,因為雙數長度的字串的中心並沒有字元,或者說在兩個字元中間,比如aabb的中心是aa#bb
,井號的位置。在演算法中我們認為中間的兩個字元是該字串的中心。所以對於每個位置,要判斷兩次,乙個是以當前位置為中心,乙個是以當前位置和後乙個字元為中心。
最長回文子串 最長回文子串行
1.最長回文子串行 可以不連續 include include include include using namespace std 遞迴方法,求解最長回文子串行 intlps char str,int i,int j intmain include include include using n...
最長回文子串
描述 輸入乙個字串,求出其中最長的回文子串。子串的含義是 在原串連續出現的字串片段。回文的含義是 正著看和倒著看是相同的,如abba和abbebba。在判斷是要求忽略所有的標點和空格,且忽略大小寫,但輸出時按原樣輸出 首尾不要輸出多餘的字串 輸入字串長度大於等於1小於等於5000,且單獨佔一行 如果...
最長回文子串
輸入乙個字元,求出其中最長的回文子串。子串的含義是 在元串中連續出現的字串片段。回文的含義是 正看和倒看相同,如abba和yyxyy,在判斷時候應該忽略所有的空格和標點符號,且忽略大小寫,但輸出應該保持原樣,輸入的字元長度不超過5000,且佔據單獨一行,輸出最長的回文子串 如有多個,輸出,起始位置最...