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. OOD沉思录 --- 类和对象的关系 --- 包含关系4

    4.9 在实现语义约束时,最好根据类定义来实现.但是这经常会导致泛滥成灾的类,在这种情况下约束应当在类的行为中实现,通常在类的构造函数中实现,但不是必须如此. 还是以汽车为例,我们看汽车的定义,为了集 ...

  2. 优秀的PHP开源项目集合

    包管理Package Management Package Management Related 框架 框架组件 微框架Micro Frameworks 内容管理系统Content Managemen ...

  3. InfluxDB Cli中查询结果中time格式显示设置

    InfluxDB Cli中,time默认显示为19位时间戳格式,平时查询起来特不方便,那么,如何设置成为我们人类能看懂的时间格式呢? 方法有二: 1.$ influx -precision rfc33 ...

  4. oracle归档日志写满错误解决方法

    最近一年,手头上负责的项目要部署到很多个地方,由于项目组里没有人对oracle比较熟悉,只能给自己增加一个DBA的角色了.由于短时间内要部署很多单位,备份策略没有设置好,结果过了一个月,用户报告程序开 ...

  5. PHP笔记(PHP高级篇)

    高级篇中将涉及数据库的使用以及Cookie和Session会话,提高PHP的开发效率和运行效率 PHP程序员需要掌握的MySQL操作 为项目设计表 使用SQL语句 MySQL的目录结构 data目录中 ...

  6. javascript 特效实现(3)—— 鼠标滑过显示二级菜单效果

    1. 关键代码:使用 switch 或 if 判断语句,改变对应的二级菜单显示方式为 block 或 none function selectTabMenu(i){ switch(i){ case 7 ...

  7. sass+compass+bootstrap三剑合璧高效开发记录

    1. 先搭建环境,下载node.js,rubyinstaller,安装, 安装rubyinstaller时,要选上include system path,这样就会自动将node.js执行添加到wind ...

  8. linux下开启SSH,并且允许root用户远程登录,允许无密码登录

    参考:http://blog.csdn.net/jia0511/article/details/8237698 1. 允许root用户远程登录 修改ssh服务配置文件 sudo vi /etc/ssh ...

  9. android:layout_gravity和android:gravity的区别

    1.首先来看看android:layout_gravity和android:gravity的使用区别. android:gravity: 这个是针对控件里的元素来说的,用来控制元素在该控件里的显示位置 ...

  10. mysql日志类型

    在MySQL中共有4中日志:错误日志.二进制日志.查询日志和慢查询日志 一.错误日志 错误日志名 host_name.err,并默认在参数DATADIR指定的目录中写入日志文件.可使用 --log-e ...