leetcode------分割回文串
解題思路:
這個簡單的方法就是,用回溯,一個個的遍歷。每一次從下一個遍歷之前,都需要判斷當前子串是不是迴文串,這裡的迴文串檢查可以用動態規劃儲存起來,加快速度:
dp[i][j]是不是迴文串,判斷s[i] == s[j] && ( j - i < 3 || dp[i+1][j-1])
class Solution {
public:
bool IsHUIWEN(string s)
{
int l = 0;
int r = s.size()-1;
while(l<r)
{
if(s[l++]!=s[r--])
return false;
}
return true;
}
void backthrough(string s,int cur,vector<string> sub,
vector<vector<string>> &res,
vector<vector<int>> &dp)
{
if(cur>=s.size())
{
res.push_back(sub);
return ;
}
for(int i = cur;i<s.size();i++)
{
//if(IsHUIWEN(s.substr(cur,i-cur+1)))
if(s[cur]==s[i] && (i-cur < 3 || dp[cur+1][i-1]))
{
dp[cur][i]=1;
sub.push_back(s.substr(cur,i-cur+1));
backthrough(s,i+1,sub,res,dp);
sub.pop_back();
}
}
}
vector<vector<string>> partition(string s) {
vector<vector<string>> res ;
vector<vector<int>> dp(s.size(),vector<int>(s.size()));
for(int i = 0;i<s.size();i++)
{
dp[i][i]=1;
}
vector<string> temp;
backthrough(s,0,temp,res,dp);
return res;
}
};
下面統計最小的分割回文串
如果沿著上一題的做法,就是將每一次分隔到最後將分割的次數記錄下來,比較大小;但這樣做還是重複記錄了很多次,會超時,從而就再需要輔助空間來降低複雜度;
我們可以從前往後遍歷,即自底向上,用dp[i] 記錄前i個字元是迴文串並且分割次數是最小的,如果j是從中的一次分割,那麼dp[j]表示前j個字元分割回文最小的次數,從0開始遍歷,如果i到j是迴文的,
那麼dp[j]=min(dp[j],dp[i]+1);意思就是說只要從i分割一刀,那麼只要前i個字串迴文分割次數最小dp[i]再加上1,就表示從i分割,此時dp[j]最小。
class Solution {
public:
bool IsHUIWEN(string s)
{
int l = 0;
int r = s.size()-1;
while(l<r)
{
if(s[l++]!=s[r--])
return false;
}
return true;
}
void backthrough(string s,int cur,int num,int &res,vector<vector<int>> &dp)
{
if(cur>=s.size())
{
res=min(res,num);
return ;
}
for(int i = cur;i<s.size();i++)
{
//if(IsHUIWEN(s.substr(cur,i-cur+1)))
if(s[cur]==s[i] && (i-cur < 3 || dp[cur+1][i-1]))
{
dp[cur][i]=1;
backthrough(s,i+1,num+1,res,dp);
}
}
}
void cut(string s ,vector<vector<int>> &dp,vector<int> &f)
{
int n = s.size();
for(int i = 1; i <= n; i++){
//表示剛開始每一處都分割一次
f[i] = i;
for(int j = 0; j < i; j++){
if(s[j]==s[i-1] && (i-1-j < 3 || dp[j+1][i-2])){
dp[j][i-1]=1;
f[i] = min(f[j] + 1, f[i]);
}
}
}
}
int minCut(string s) {
int res = 999;
vector<vector<int>> dp(s.size(),vector<int>(s.size()));
for(int i = 0;i<s.size();i++)
{
dp[i][i]=1;
}
vector<int> f(s.size()+1);
f[0]=-1;
//f[0]是-1很重要,表示從0開始到j就是迴文的,那麼f[0]+1 = 0表示不需要進行分割。
cut(s,dp,f);
return f[s.size()];;
}
};
相關文章
- LeetCode-131-分割回文串LeetCode
- LeetCode 分割回文串II(動態規劃)LeetCode動態規劃
- 回溯演算法 LeetCode 131 分割回文子串演算法LeetCode
- leetcod 131.分割回文串(回溯、迴文字串)字串
- 【LeetCode刷題(困難程度)】132. 分割回文串 IILeetCode
- Python找回文子串的方法Python
- Day 26| 39. 組合總和 、 40.組合總和II 、 131.分割回文串
- LeetCode 39. 組合總和 40.組合總和II 131.分割回文串LeetCode
- URAL 1297. Palindrome(字尾陣列求最大回文串)陣列
- 程式碼隨想錄演算法訓練營第23天 | 39.組合總和 40.組合總和Ⅱ 131.分割回文串演算法
- 程式碼隨想錄演算法訓練營第27天 | 39. 組合總和 、 40.組合總和II 、 131.分割回文串演算法
- 程式碼隨想錄演算法訓練營,9月19日 | 39. 組合總和,40.組合總和II,131.分割回文串演算法
- 程式碼隨想錄演算法訓練營第26天 | 回溯02:39. 組合總和、40.組合總和II、131.分割回文串演算法
- Leetcode:1616. 分割兩個字串得到迴文串LeetCode字串
- 今日面試題:最長迴文子串;及迴文分割分析面試題
- 27天【程式碼隨想錄演算法訓練營34期】第七章 回溯演算法part03(● 39. 組合總和 ● 40.組合總和II ● 131.分割回文串)演算法
- POJ 1159 Palindrome(字串變回文:LCS)字串
- 程式碼隨想錄演算法訓練營第二十三天| leetcode39. 組合總和、leetcode40.組合總和II、leetcode131.分割回文串演算法LeetCode
- 子串查詢;及排列子串分析
- 串的基本運算實現-加密解密串加密解密
- 子串位置
- 假設串S1 = "I come from Beijing",S2 = "Chongqing" ,Sub = "America". 利用串的基本操作,如果串的賦值、串的插入、串的刪除、串的替換、對上面賦值
- 子串查詢
- 查詢子串
- C# 格式串C#
- 最長子串
- (迴文串)leetcode各種迴文串問題LeetCode
- 資料結構---串資料結構
- [leetcode 30 串聯所有單詞的子串 10ms]LeetCode
- 四種命名介紹:駝峰、帕斯卡、蛇形、烤串(肉串)
- poj3080-kmp+列舉子串 求最長公共子串KMP
- ES6字串字串
- 串的簡單處理
- Java 的字串和子串Java字串
- day7字串字串
- lCS(最長公共子串)
- 04.子串,啟動!
- POJ 3294 Life Forms(字尾陣列求k個串的最長子串)ORM陣列