有關回文串的問題可以用很多種演算法來解決,比如:專門為解決回文串而設計的演算法manacher 演算法,馬拉車演算法等等,可以看這裡 。而本文只關心用動態規劃的方法來解決。
文章涉及到 求
最長回文子串 leetcode 5
最長回文子串行 leetcode 516
最少分割次數使得都為回文子串 leetcode 132
最少插入次數使得為回文子串 leetcode 1312
對待回文串問題的動態規劃狀態定義,一般有兩個
對於狀態的定義要和題目所求的量搭上關係
狀態轉移方程思考也有兩個途徑
1.最長回文子串 leetcode 5
狀態定義
dp[i][j] 表示字串 s 的第 i 到 j 個字母組成的串 s[i…j]是否為回文串
狀態轉移方程
dp[i][j] = dp[i+1][j-1] && (s[i]==s[j])
base case
i == j 時 dp[i][j] = 1
class solution
}return ans;}};
2.最長回文子串行 leetcode 516
狀態定義
dp[i][j]表示在子串 s[i…j] 中,最長回文子串行的長度為 dp[i][j]
狀態轉移方程
if (s[i] == s[j])
dp[i][j] = dp[i + 1][j - 1] + 2; // s[i] s[j]都在最長回文子串行中
else
dp[i][j] = max(dp[i + 1][j], dp[i][j - 1]); // s[i+1..j] 和 s[i..j-1] 誰的回文子串行更長?
base case
i == j 時 dp[i][j] = 1
class solution
for( int i = n-1; i >= 0; i -- )
}return dp[0][n-1];}};
3.最少分割次數使得都為回文子串 leetcode 132這道題的上一題leetcode131 求所有的分割方法,使用回溯法來解決。動態規劃就是需要窮舉出所有答案再求最值,回溯法只是窮舉出答案,這道題要求最小分割次數,所以用動態規劃來求解。
並且這裡分割,很明顯不能使用中心擴散的方法,所以只能使用一維dp
狀態定義
dp[i]:表示字首子串 s[0…i] 分割成若干個回文子串所需要最小分割次數。
狀態轉移方程
if (s[0:i] 本身就是乙個回文串)
那麼不用分割 dp[i] = 0
else
for j in (0..i)
if (s[j + 1, i] 是回文])
dp[i] = min( dp[i], [dp[j] + 1 )
base case
單個字元一定是回文串 dp[0] = 0;
class solution
return true;
}public:
int mincut(string s) }}
return dp[n-1];}};
4.最少插入次數使得為回文子串 leetcode 1312狀態定義
dp[i][j] 表示s[i…j],最少需要進行dp[i][j]次插入才能變成回文串
狀態轉移方程
if(s[i] == s[j])
dp[i][j] = dp[i+1][j-1];
else
dp[i][j] = min( dp[i+1][j], dp[i][j-1] ) + 1;
base case
i == j時 dp[i][j] = 0
class solution
}return dp[0][n-1];}};
回文串問題(動態規劃DP C )
乙個字串,如果從左到右讀和從右到左讀是完全一樣的,比如 aba 我們稱其為回文串。現在給你乙個字串,可在任意位置新增字元,求最少新增幾個字元,才能使其變成乙個回文串。任意給定的乙個字串,其長度不超過1000.能變成回文串所需新增的最少字元數。在這裡給出一組輸入。例如 ab3bdabb在這裡給出相應的...
動態規劃實現回文字串問題
問題一 求乙個字串的最大回文字串長度 1 思路 動態規劃 2 具體描述 設立乙個長度len為字串str,用乙個dp len len 的二維陣列來表示字串i j下標所構成的子串的長度,經過迴圈計算之後我們返回最大回文子串的長度即可,即返回dp 0 len 1 3 dp陣列的具體實現 根據動態規劃自底向...
回文串劃分(動態規劃)
題目描述 給出乙個字串 s,對這個字串進行切分,每個子串都必須是乙個回文字串,問最少要切多少次。example 給出 s aab 返回最少切分次數 1。因為只需要一次切分就能把 s 切分成符合要求的兩個子串 aa b 暴力法 列舉起點和終點去求該區間字串的最長回文字串 時間複雜度o n 2 找到後就...