LeetCode 回文串專題

2022-01-29 20:35:19 字數 3891 閱讀 7265

【leetcode】5.最長回文子串

【leetcode】680. 驗證回文字串 ⅱ

【leetcode】5.最長回文子串

給定乙個字串s,找到s中最長的回文子串。你可以假設s的最大長度為 1000。

示例 1

:輸入:

"babad

"輸出:

"bab

"注意:

"aba

"也是乙個有效答案。

示例 2

:輸入:

"cbbd

"輸出: "bb

"

(1)暴力求解

字串問題,首先就是想到暴力的方法。

找出字串s的所有子串,並對所有子串進行判斷其是否為回文串,如果字串s有多個不同長度的回文子串,則用ans以及maxx迭代更新最長回文子串以及最長回文子串的長度。時間複雜度為o(n3),基本上是超時的。

(2)中心擴充套件法

思路:(3)動態規劃(本題的解法與lcs型別)

動態規劃一般也只能應用於有最優子結構的問題。最優子結構的意思是區域性最優解能決定全域性最優解(對有些問題這個要求並不能完全滿足,故有時需要引入一定的近似)。簡單地說,問題能夠分解成子問題來解決。

動態規劃演算法分以下4個步驟:(1

)描述最優解的結構(2

)遞迴定義最優解的值

(3)按自底向上的方式計算最優解的值 //

此3步構成動態規劃解的基礎。

(4)由計算出的結果構造乙個最優解。 //

此步如果只要求計算最優解的值時,可省略。

好,接下來,咱們討論適合採用動態規劃方法的最優化問題的倆個要素:最優子結構性質,和子問題重疊性質。(1

)最優子結構

如果問題的最優解所包含的子問題的解也是最優的,我們就稱該問題具有最優子結構性質(即滿足最優化原理)。意思就是,總問題包含很多個子問題,而這些子問題的解也是最優的。(2

)重疊子問題

子問題重疊性質是指在用遞迴演算法自頂向下對問題進行求解時,每次產生的子問題並不總是新問題,有些子問題會被重複計算多次。動態規劃演算法正是利用了這種子問題的重疊性質,對每乙個子問題只計算一次,然後將其計算結果儲存在乙個**中,當再次需要計算已經計算過的子問題時,只是在**中簡單地檢視一下結果,從而獲得較高的效率。

該問題滿足最優子結構性質:乙個最長回文串去掉兩頭以後,剩下的部分依然是最長回文串。

第一步:定義狀態

dp[i][j]:表示子串s[i,j]是否為回文子串。

當dp[i][j] = 1:表示子串s[i,j]為回文子串,反之。

第二步:狀態轉移方程

這一步在做分類討論(根據頭尾字元是否相等)。

if j-i >= 2

dp[i][j] = 1, if dp[i+1][j-1] == 1 && s[i] == s[j]

dp[i][j] = 0, if dp[i+1][j-1] == 0 || s[i] != s[j]

else

dp[i][j] = 1,if s[i] == s[j]

dp[i][j] = 0,if s[i] != s[j]

q:j-i >= 2這個條件是如何求解出來的?

a:因為dp[i][j]表示子串s[i,j]是否為回文子串,所以i<=j,同理dp[i+1][j-1]中,i+1 <= j-1,整理得j - i <= 2.

第三步:考慮初始化

初始化的時候,單個字元一定是回文串,因此把對角線先初始化為 1,即 dp[i][i] = 1 。

第四步:考慮輸出

只要一得到dp[i][j] = 1,就記錄子串的長度和起始位置,沒必要利用substr函式擷取,因為擷取字串也要消耗效能,記錄此時的回文子串的「起始位置」和「回文長度」即可。

第五步:考慮狀態是否可以壓縮

因為在填表的過程中,只參考了左下方的數值。事實上可以壓縮,但會增加一些判斷語句,增加**編寫和理解的難度,丟失可讀性。在這裡不做狀態壓縮。

(4)觀察法

觀察子串,回文字數要麼是偶數個,那麼類似cbaabc這種中間是aa的;要麼是奇數個,類似是cbabc中間是bab型的,僅此兩種。所以用for先找偶數型(aa)回文,找s[i]=s[i+1],找到後再往兩邊推,直到s[i-len]與s[i+1+len]不等為止,記錄此子串的位置和長度,最後進行長度比較。再找s[i]=s[i+2],即找奇數型(aba)回文,找到後處理同上。

(2) 中心擴充套件法

1

class

solution 6//

記錄最長回文子串開始和結束的位置。

7int start = 0, end = 0;

8for (int i = 0; i < s.length(); i++) 19}

20return s.substring(start, end + 1);21}

2223

private

int function(string s, int left, int

right)

29return right - left - 1;30}

31 }

(3)動態規劃法

1

class

solution

18else

1923

24if(dp[i][j] == 1 && j-i+1>len) //迭代更新,利用len記錄回文串的最大長度

2529}30

}31if(len == 0) return s.substr(0,1

);32

else

return

s.substr(index,len);33}

34 };

(4)觀察法

1

class

solution 21}

22}23for (i = 0; i < slen-1; i++)//

該for迴圈判斷cbabc型別的回文串

2435}36

}37if (max==0)38

return s.substr(0,1

);39

else

40return

s.substr(t, max);41}

42 };

【leetcode】680. 驗證回文字串 ⅱ

給定乙個非空字串 s,最多刪除乙個字元。判斷是否能成為回文字串。

示例 1

:輸入:

"aba

"輸出: true

示例 2

:輸入:

"abca

"輸出: true

解釋: 你可以刪除c字元。

注意:字串只包含從 a-z 的小寫字母。字串的最大長度是50000。

先判斷字串s是否為回文字串,如果是則返回true,如果不是按順序刪除字串s中的每乙個字元,然後判斷剩餘的字串是否為回文字串即可。

當檢查到前後不一樣的字元,必須要刪掉乙個(要麼開頭,要麼結尾)。刪掉之後檢查剩下的字串是否為回文。是則返回true,反之。

1

class

solution

13return

true;14

}15bool validpalindrome(string

s) 26

else

2735}36

return

true;37

}38 };

leetcode專題 回文串問題

具體問題具體分析,往往思路就是從這裡來的。回文問題主要是判斷回文的時間複雜度太高,可以考慮dp 雜湊表 字典樹 字串雜湊 kmp 馬拉車等優化對回文的判斷。336.回文對 有些問題可以先嘗試,說不定能通過,但是形如o n 或者指數級複雜度就可以不考慮了。一般是子串行問題,迫不得已,沒辦法直接中心擴充...

LeetCode 驗證回文串

題目描述 給定乙個字串,驗證它是否是回文串,只考慮字母和數字字元,可以忽略字母的大小寫。說明 本題中,我們將空字串定義為有效的回文串。示例 1 輸入 a man,a plan,a canal panama 輸出 true 示例 2 輸入 race a car 輸出 false class solut...

Leetcode 最短回文串

題目鏈結 只是在馬發車演算法基礎上改動了最後的處理方式,因為這道題限制在字串前面新增字元,所以必須回文子串的起始位置在s字串的開頭才能。class solution string t for int i 0 ii else while t i p i 1 t i p i 1 if i p i r c...