回文字符串及其变种
回文partition一般有以下几种情况:
1. 求所有的partition结果。这个一般用DFS来解。
2. 最后结果是一个整数,比如Palindrome Partitioning II。这个用DP来解
3. 最后求一个结果,比如最小切法。这个用DP+backtrack来解
4. 最长回文子串
问题1:求所有的回文partition结果,用简单的DFS就可以求出。
bool isPalin(string &s,int l,int r)
{
while(l<r)
{
if(s[l]!=s[r])
return false;
l++;
r--;
}
return true;
}
vector<vector<string>> partition(string s) {
// Start typing your C/C++ solution below
// DO NOT write int main() function
//DFS
vector<vector<string>> res;
if(s.empty())
return res;
vector<string> path;
dfs(s,0,path,res);
return res;
}
void dfs(string& s,int curpos,vector<string>& path,vector<vector<string>>& res)
{
if(curpos==s.size())
{
res.push_back(path);
return;
}
for(int i=curpos;i<s.size();i++)
{
if(isPalin(s,curpos,i))
{
path.push_back(s.substr(curpos,i-curpos+1));
dfs(s,i+1,path,res);
path.pop_back();
}
}
}
---改进版,用一个二维数组预处理子串是否回文,避免上面解法重复计算子串回文。
vector<vector<string>> partition(string s) {
// Start typing your C/C++ solution below
// DO NOT write int main() function
vector<vector<string>> res;
if(s.empty())
return res;
int n = s.size();
vector<vector<bool>> palin;
for(int i=0;i<n;i++)
palin.push_back(vector<bool>(n));
for(int i=0;i<n;i++)
palin[i][i] = true;
for(int i=n-2;i>=0;i--) //注意:这里从i大的开始,从0开始时错误的,因为例如计算palin[0][5]需要palin[1][4],而palin[1][4]此时是未初始化的。
{
if(s[i]==s[i+1])
palin[i][i+1] = true;
else palin[i][i+1] = false;
for(int j=i+2;j<n;j++)
{
if(palin[i+1][j-1]&&s[i]==s[j])
palin[i][j] = true;
else palin[i][j] = false;
}
}
vector<string> path;
dfs(0,s,path,palin,res);
return res;
}
void dfs(int pos,string& s,vector<string>& path,vector<vector<bool>>& palin,vector<vector<string>>& res)
{
if(pos==s.size())
{
res.push_back(path);
return;
}
for(int i=pos;i<s.size();i++)
{
if(palin[pos][i])
{
path.push_back(s.substr(pos,i-pos+1));
dfs(i+1,s,path,palin,res);
path.pop_back();
}
}
}
问题2:求回文最小partition个数。---DP求解
浙公网安备 33010602011771号