您的位置:首页 > 其它

Leetcode: palindrome-partitioning && palindrome-partitioning-ii

2018-01-15 21:40 375 查看
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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: