palindrome-partitioning
Given a string s, partition s such that every substring ofthe partition is a palindrome.
Return the minimum cuts needed for a palindrome partitioning of s.
For example, given s ="aab",
Return1since the palindromepartitioning["aa","b"]could be produced using 1 cut.
思想:这个和寻路的思想基本一样,用深度搜索即可,在判定遍历后的字符串是回文字符串之后,再递归调用函数遍历剩余未遍历的字符串。主要是记得回溯恢复状态
代码:
vector<vector<string>> partition(string s) {
vector<vector<string>> d2_tmp;
vector<string> tmp;
dfs(s,tmp,d2_tmp);
return d2_tmp;
}
void dfs(string s,vector<string>& tmp, vector<vector<string>>& d2_tmp)
{
if(s.empty())
{
d2_tmp.push_back(tmp);
return;
}
int len = s.size();
for(int i=0; i!=len; i++)
{
if(Is_palindr(s.substr(0,i+1)))
{
tmp.push_back(s.substr(0,i+1)); //dfs的精髓在于需要回溯,这里的push_back再pop_back就是回溯
dfs(s.substr(i+1,len-(i+1)),tmp,d2_tmp);
tmp.pop_back();
}
}
}
bool Is_palindr(string s)
{
int len=s.size();
for(int i=0,j=len-1; i<j; i++, j--)
{
if(s[i] != s[j])
return false;
}
return true;
}
palindrome-partitioning-ii
Given a string s, partition s such that every substring of the partitionis a palindrome.
Return the minimum cuts needed for a palindrome partitioning of s.
For example, given s ="aab",
Return1since the palindrome partitioning["aa","b"]could beproduced using 1 cut.
思路:什么求极值(最小切割,最大切割,总共最多多少种…)的算法一般来说,都和动态规划有关。因此用动态规划解决。初始状态是一个字符串它自身的字符所处的位置下标是多少,就会被切割多少次,也就是初始化状态为最大切割数。同时,对于0到i为回文的,切割数置为0(回文不用切割)。
for(int i=0; i!=len; i++)
{
dp[i] = i;
if(Is_palindr(s.substr(0,i+1)))
dp[i]=0;
}
dp[i]表示从开始到i能被切割的最小次数。那么它和状态有关呢?假设有个字符串为“aabbaacc”。长度为8,假设遍历已经遍历到第5个字符(下标从0开始),也就是i=5。
a a b b a a c c
j i
此时dp[i=5]的最小切割数和dp[j-1]以及j到i的字符串是否为回文有关,dp[j]表示开始到j的最小切割数,既然已经求dp[i]的最小切割数,那么dp[j]的最小切割数肯定已知。
这时,假设j到i这段区间的字符串为回文的话,那么最少只需切一次即可(当然若初始化的时候dp[i]=0,那么肯定是dp[i]=0),那么整体0到i的最小切割数为0到j-1的最小切割数dp[j-1]再加1。即dp[i]=dp[j-1]+1。
若不是回文,则dp[i]=dp[j-1]+i-j+1。即加上j到i的长度。这就是状态转移方程。j是由i开始从左往右遍历的。
最后比较并保存最小。
代码:
int minCut(string s) {
int len = s.size();
vector<int> dp(len);
for(int i=0; i!=len; i++)
{
dp[i] = i;
if(Is_palindr(s.substr(0,i+1)))
dp[i]=0;
}
for(int i=1; i!=len; i++)
{
for(int j=i; j>0; j--)
{
if(Is_palindr(s.substr(j,i-j+1)))
dp[i] = min(dp[i],dp[j-1]+1);
else
dp[i] = min(dp[i],dp[j-1]+i-j+1);
}
}
return dp[len-1];
}
bool Is_palindr(string s)
{
int len=s.size();
for(int i=0,j=len-1; i<j; i++, j--)
{
if(s[i] != s[j])
return false;
}
return true;
}