【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) 中心擴充套件法
1class
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)動態規劃法
1class
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)觀察法
1class
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,反之。
1class
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...