LeetCode:Palindrome Partitioning

题目如下:(把一个字符串划分成几个回文子串,枚举所有可能的划分)

Given a string s, partition s such that every substring of the partition is a palindrome.

Return all possible palindrome partitioning of s.

For example, given s = "aab",
Return

[
["aa","b"],
["a","a","b"]
]

分析:首先对字符串的所有子串判断是否是回文,设f[i][j] = true表示以i为起点,长度为j的子串是回文,等于false表示不是回文,那么求f[i][j]的动态规划方程如下:

  • 当j = 1,f[i][j] = true;

  • 当j = 2,f[i][j] = (s[i]==s[i+1]),其中s是输入字符串

  • 当j > 2, f[i][j] = f[i+1][j-2] && (s[i] == s[i+j-1])(即判断s[m..n]是否是回文时:只要s[m+1...n-1]是回文并且s[m] = s[n],那么它就是回文,否则不是回文)

这一题也可以不用动态规划来求f,可以用普通的判断回文的方式判断每个子串是否为回文。                                                                                                               本文地址

求得f后,根据 f 可以构建一棵树,可以通过DFS来枚举所有的分割方式,代码如下:

 class Solution {
public:
vector<vector<string>> partition(string s) {
// IMPORTANT: Please reset any member data you declared, as
// the same Solution instance will be reused for each test case.
vector< vector<string> >res;
int len = s.length();
if(len == )return res;
//f[i][j] = true表示以i为起点,长度为j的子串是回文
bool **f = new bool*[len];
for(int i = ; i < len; i++)
{
f[i] = new bool[len+];
for(int j = ; j < len+; j++)
f[i][j] = ;
f[i][] = true;
}
for(int k = ; k <= len; k++)
{
for(int i = ; i <= len-k; i++)
{
if(k == )f[i][] = (s[i] == s[i+]);
else f[i][k] = f[i+][k-] && (s[i] == s[i+k-]);
}
}
vector<string> tmp;
DFSRecur(s, f, , res, tmp);
for(int i = ; i < len; i++)
delete [](f[i]);
delete []f;
return res;
} void DFSRecur(const string &s, bool **f, int i,
vector< vector<string> > &res, vector<string> &tmp)
{//i为遍历的起点
int len = s.length();
if(i >= len){res.push_back(tmp); return;}
for(int k = ; k <= len - i; k++)
if(f[i][k] == true)
{
tmp.push_back(s.substr(i, k));
DFSRecur(s, f, i+k, res, tmp);
tmp.pop_back();
} }
};

LeetCdoe:Palindrome Partitioning II

题目如下:(在上一题的基础上,找出最小划分次数)

Given a string s, partition s such that every substring of the partition is a palindrome.

Return the minimum cuts needed for a palindrome partitioning of s.

For example, given s = "aab",
Return 1 since the palindrome partitioning ["aa","b"] could be produced using 1 cut.                                                                                                          本文地址

算法1:在上一题的基础上,我们很容易想到的是在DFS时,求得树的最小深度即可(遍历时可以根据当前求得的深度进行剪枝),但是可能是递归层数太多,大数据时运行超时,也贴上代码:

 class Solution {
public:
int minCut(string s) {
// IMPORTANT: Please reset any member data you declared, as
// the same Solution instance will be reused for each test case.
int len = s.length();
if(len <= )return ;
//f[i][j] = true表示以i为起点,长度为j的子串是回文
bool **f = new bool*[len];
for(int i = ; i < len; i++)
{
f[i] = new bool[len+];
for(int j = ; j < len+; j++)
f[i][j] = ;
f[i][] = true;
}
for(int k = ; k <= len; k++)
{
for(int i = ; i <= len-k; i++)
{
if(k == )f[i][] = (s[i] == s[i+]);
else f[i][k] = f[i+][k-] && (s[i] == s[i+k-]);
}
}
int res = len, depth = ;
DFSRecur(s, f, , res, depth);
for(int i = ; i < len; i++)
delete [](f[i]);
delete []f;
return res - ;
}
void DFSRecur(const string &s, bool **f, int i,
int &res, int &currdepth)
{
int len = s.length();
if(i >= len){res = res<=currdepth? res:currdepth; return;}
for(int k = ; k <= len - i; k++)
if(f[i][k] == true)
{
currdepth++;
if(currdepth < res)
DFSRecur(s, f, i+k, res, currdepth);
currdepth--;
} } };

算法2:设f[i][j]是i为起点,长度为j的子串的最小分割次数,f[i][j] = 0时,该子串是回文,f的动态规划方程是:

f[i][j] = min{f[i][k] + f[i+k][j-k] +1} ,其中 1<= k <j

这里f充当了两个角色,一是记录子串是否是回文,二是记录子串的最小分割次数,可以结合上一题的动态规划方程,算法复杂度是O(n^3), 还是大数据超时,代码如下:

 class Solution {
public:
int minCut(string s) {
// IMPORTANT: Please reset any member data you declared, as
// the same Solution instance will be reused for each test case.
int len = s.length();
if(len <= )return ;
//f[i][j] = true表示以i为起点,长度为j的子串的最小切割次数
int **f = new int*[len];
for(int i = ; i < len; i++)
{
f[i] = new int[len+];
for(int j = ; j < len+; j++)
f[i][j] = len;
f[i][] = ;
}
for(int k = ; k <= len; k++)
{
for(int i = ; i <= len-k; i++)
{
if(k == && s[i] == s[i+])f[i][] = ;
else if(f[i+][k-] == &&s[i] == s[i+k-])f[i][k] = ;
else
{
for(int m = ; m < k; m++)
if(f[i][k] > f[i][m] + f[i+m][k-m] + )
f[i][k] = f[i][m] + f[i+m][k-m] + ;
}
}
}
int res = f[][len], depth = ;
for(int i = ; i < len; i++)
delete [](f[i]);
delete []f;
return res;
}
};

算法3:同上一题,用f来记录子串是否是回文,另外优化最小分割次数的动态规划方程如下,mins[i] 表示子串s[0...i]的最小分割次数:

  • 如果s[0...i]是回文,mins[i] = 0
  • 如果s[0...i]不是回文,mins[i] = min{mins[k] +1 (s[k+1...i]是回文)  或  mins[k] + i-k  (s[k+1...i]不是回文)} ,其中0<= k < i

代码如下,大数据顺利通过,结果Accept:                                                                                                                                 本文地址

 class Solution {
public:
int minCut(string s) {
// IMPORTANT: Please reset any member data you declared, as
// the same Solution instance will be reused for each test case.
int len = s.length();
if(len <= )return ;
//f[i][j] = true表示以i为起点,长度为j的子串是回文
bool **f = new bool*[len];
for(int i = ; i < len; i++)
{
f[i] = new bool[len+];
for(int j = ; j < len+; j++)
f[i][j] = false;
f[i][] = true;
}
int mins[len];//mins[i]表示s[0...i]的最小分割次数
mins[] = ;
for(int k = ; k <= len; k++)
{
for(int i = ; i <= len-k; i++)
{
if(k == )f[i][] = (s[i] == s[i+]);
else f[i][k] = f[i+][k-] && (s[i] == s[i+k-]);
}
if(f[][k] == true){mins[k-] = ; continue;}
mins[k-] = len - ;
for(int i = ; i < k-; i++)
{
int tmp;
if(f[i+][k-i-] == true)tmp = mins[i]+;
else tmp = mins[i]+k-i-;
if(mins[k-] > tmp)mins[k-] = tmp;
}
}
for(int i = ; i < len; i++)
delete [](f[i]);
delete []f;
return mins[len-];
} };

 【版权声明】转载请注明出处:http://www.cnblogs.com/TenosDoIt/p/3421283.html

LeetCode:Palindrome Partitioning,Palindrome Partitioning II的更多相关文章

  1. [LeetCode] 680. Valid Palindrome II 验证回文字符串 II

    Given a non-empty string s, you may delete at most one character. Judge whether you can make it a pa ...

  2. [LeetCode] 214. Shortest Palindrome 最短回文串

    Given a string s, you are allowed to convert it to a palindrome by adding characters in front of it. ...

  3. LeetCode 1216. Valid Palindrome III

    原题链接在这里:https://leetcode.com/problems/valid-palindrome-iii/ 题目: Given a string s and an integer k, f ...

  4. [LeetCode] 409. Longest Palindrome 最长回文

    Given a string which consists of lowercase or uppercase letters, find the length of the longest pali ...

  5. leetcode bug & 9. Palindrome Number

    leetcode bug & 9. Palindrome Number bug shit bug "use strict"; /** * * @author xgqfrms ...

  6. leetcode 第九题 Palindrome Number(java)

    Palindrome Number time=434ms 负数不是回文数 public class Solution { public boolean isPalindrome(int x) { in ...

  7. leetcode@ [131/132] Palindrome Partitioning & Palindrome Partitioning II

    https://leetcode.com/problems/palindrome-partitioning/ Given a string s, partition s such that every ...

  8. 乘风破浪:LeetCode真题_040_Combination Sum II

    乘风破浪:LeetCode真题_040_Combination Sum II 一.前言 这次和上次的区别是元素不能重复使用了,这也简单,每一次去掉使用过的元素即可. 二.Combination Sum ...

  9. [LeetCode] 445. Add Two Numbers II 两个数字相加之二

    You are given two linked lists representing two non-negative numbers. The most significant digit com ...

随机推荐

  1. bsearch

    在java中为了避免 low+high溢出,可以用无符号右移:正数高位补0,负数高位补1 int mid = (low + high) >>> 1; 如果是在c++中,那么需要先转换 ...

  2. GDI学习之俄罗斯方块续

    当前方块对象 #region 定义砖块int[i,j,y,x] Tricks:i为那块砖,j为状态,y为列,x为行 private int[, , ,] Tricks = {{ { {,,,}, {, ...

  3. jQuery Validate 表单验证插件----自定义一个验证方法

    一.下载依赖包 网盘下载:https://yunpan.cn/cryvgGGAQ3DSW  访问密码 f224 二.引入依赖包 <script src="../../scripts/j ...

  4. 数据结构--树状数组(黑龙江省第八届大学生程序设计竞赛--post office)

    例题来源: 题目: 1468: Post office 题目描述 There are N(N<=1000) villages along a straight road, numbered fr ...

  5. jQuery事件绑定on、off 和one,取代bind, live, delegate

    jQuery最新版建议:最好用on来代替以前的bind, live, delegate,其中live是最不建议使用的. on和off的格式 on $(elements).on(events[, sel ...

  6. myeclipe eclipse 常遇问题:Some projects cannot be imported 、java.lang.ClassNotFoundException: oracle.jdbc.driver.OracleDriver、The file connot be validate

    1.Some projects cannot be imported because they already exist in the workspace 2.Some projects were ...

  7. Mathout 安装部署

    安装Mahout,并运行测试样例,抓图测试实验过程 证明已部署成功 Mahout 下载地址:http://apache.dataguru.cn/mahout/0.9/mahout-distributi ...

  8. nopcommerce里面的@Html.Widget("home_page_top") 是什么?

    很多朋友在修改模板的时候看到很多类似@Html.Widget("xxx")的东西,这里简单介绍一下流程: 比如@Html.Widget("home_page_top&qu ...

  9. 关于volatile和synchronized

    这个可能是最好的对比volatile和synchronized作用的文章了.volatile是一个变量修饰符,而synchronized是一个方法或块的修饰符.所以我们使用这两种关键字来指定三种简单的 ...

  10. 机器学习:logistic回归

    逻辑回归是一个形式是Y=1/(1+E(-X))的函数,它的特点是: 1, 当X>0,随着X增大,Y很快的接近1: 2,当x<0,随着X的减小,Y很快的接近0: 3,当X=0时,Y=1/2. ...