(1) Palindrome Partitioning
动态规划,划分的时候判断dp_map[i][j]是否是回文串,需要用到dp_map[i+1][j-1]的值[1]:
class Solution {
private:
void dp(string s, vector<vector<int>>& dp_map) {
for(int i=s.size()-1;i>=0;i--)
for(int j=i;j<s.size();j++)
{
if(i==j)
dp_map[i][j]=1;
else
{
if(s[i]==s[j])
{
if(i+1==j || dp_map[i+1][j-1]==1)
dp_map[i][j]=1;
}
}
}
}
void dfs(int dep, string &s, vector<vector<int>>& dp_map, vector<string> tmp, vector<vector<string>> &ret) {
if(dep==s.size())
{
ret.push_back(tmp);
return;
}
for(int i=dep;i<s.size();i++)
{
if(dp_map[dep][i]==1)
{
vector<string> tmp1(tmp);
tmp1.push_back(s.substr(dep,i-dep+1));
dfs(i+1,s,dp_map,tmp1,ret);
}
}
}
public:
vector<vector<string>> partition(string s) {
vector<vector<int>> dp_map(s.size(),vector<int>(s.size(),0));
vector<string> tmp;
vector<vector<string>> ret;
if(s.size()==0)
return ret;
tmp.clear();
ret.clear();
dp(s,dp_map);
dfs(0,s,dp_map,tmp,ret);
return ret;
}
};
注意用到二维数组时使用二维的vector来表达,这样可以免去一般二维数组的复杂传参。
(2) Palindrome Partitioning II
本来想在(1)的基础上在算出所有的可能切割组合中选一个最短的,还是超时了通不过。所以在寻找最少cut的时候还是得使用动态规划。这道题目的状态转移方程为:dp[i]=min(dp[j])+1,其中j>=0&&j<i&&p[j+1][i]是回文串,p[i][j]用来表示i-j之间是否是回文串[2]:
class Solution {
private:
int dp(string s, vector<vector<int>>& dp_map) {
for(int i=s.size()-1;i>=0;i--)
for(int j=i;j<s.size();j++)
{
if(i==j)
dp_map[i][j]=1;
else
{
if(s[i]==s[j])
{
if(i+1==j || dp_map[i+1][j-1]==1)
dp_map[i][j]=1;
}
}
}
int tmp;
vector<int> dp_min(s.size(),0);
for(int i=1;i<s.size();i++)
{
if(dp_map[0][i]==1)
{
dp_min[i]=0;
continue;
}
tmp=numeric_limits<int>::max();
for(int j=0;j<i;j++)
{
if(dp_map[j+1][i]==1)
{
if(dp_min[j]+1<tmp)
tmp=dp_min[j]+1;
}
}
dp_min[i]=tmp;
}
return dp_min[s.size()-1];
}
public:
int minCut(string s) {
vector<vector<int>> dp_map(s.size(),vector<int>(s.size(),0));
if(s.size()<=1)
return 0;
return dp(s,dp_map);
}
};
参考:
[1] http://blog.csdn.net/worldwindjp/article/details/22042133
[2] http://blog.csdn.net/chen895281773/article/details/8780366