LeetCode131: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"]
]
解题思路:
这道题跟Word Break II这道基本一样,需要用DP+DFS解决
这里采用DP中的自底向上实现,dp[i]表示前i个字符是否为切分为多个回文字符串。当求解dp[i]时,可利用已经求解的dp[i-1],
dp[i-2]…dp[1],dp[0]进行求解。
对于dp[n]的求解,我们可以将n个字符进行切分求解,分为前i个字符和后n-i个字符,i可以为(0,1,2,3,4…n-1)
假设i为1时,可根据dp[i]和后面的n-1个字符组成的单词是否在dict中来判断dp[n],只要i(0,1,2,3,4…n-1)其中一种
情况为真,则dp[n]为true,表示可以进行切分为多个回文字符串。
因为本题需要重构结果,所以必须要有一个数据结构来保存每段长度的切割方案,这里我用unordered_map<int, vector<int> >进行保存,key为字符长度,vector保存该key对应的切割方案。
如何求得unordered_map<int, vector<int> >中的值呢?那就应该利用求解dp[i]时,每当有一种切割方案使得dp[i]为true时,将其对应的切割位置存放到i对应的vector中,待之后用于结果重构。
unordered_map<int, vector<int> >求得后,接下来是采用DFS算法进行结果重构,如代码执行结果图,当长度为3时,有一种切割方案,即在长度为2的位置进行切割,然后长度为2的切割方案又有两种0和1,长度为1时,切割方案都为0,所以采用DFS时,遍历顺序为2,0然后获得一种结果,之后回溯到2,1,因为1的切割方案为0,所以为3,1,0,又是一种结果。
实现代码:
#include <iostream>
#include <vector>
#include <iterator>
#include <unordered_map>
#include <string>
#include <algorithm> using namespace std;
/*
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"]
]
*/
class Solution {
public:
//DP
vector<vector<string>> partition(string s) {
vector<vector<string>> retvec;
if(s.size() == 0)
return retvec;
int len = s.size();
vector<bool> dp(len+1, false);//前i个字符是否为回文数
dp[0] = true;
unordered_map<int, vector<int>> hashtable;//对前i个字符,如果其为回文数时的切分点
for(int i = 1; i <= len; i++)
{
vector<int> tmpv;
for(int j = 0; j < i; j++)
{
if(dp[j] && isPalindrome(s.substr(j, i-j)) )
{
dp[i] = true;
tmpv.push_back(j); }
}
hashtable[i] = tmpv;
} for(int k = 1; k <= len; k++)
{
vector<int> tvec = hashtable[k];
cout<<k<<":";
copy(tvec.begin(), tvec.end(), ostream_iterator<int>(cout, " "));
cout<<endl;
}
vector<int> curvec;
getResult(retvec, hashtable, s, len, curvec);
return retvec; }
bool isPalindrome(string s)
{
int len = s.size();
if(len == 0)
return false;
for(int i = 0; i <= len/2; i++)
if(s[i] != s[len-i-1])
return false;
return true;
} //DFS
void getResult(vector<vector<string>> &retvec, unordered_map<int, vector<int>> &hashtable, string &s, int len, vector<int> &curvec)
{
if(len == 0)
{
vector<string> tv;
int start = curvec.back();
for(int i = curvec.size()-2; i >= 0; i--)
{
int c = curvec[i];
tv.push_back(s.substr(start, c-start));
start = c;
}
tv.push_back(s.substr(curvec[0]));
retvec.push_back(tv);
return ;
}
vector<int> tmpv = hashtable[len];
vector<int>::iterator iter;
for(iter = tmpv.begin(); iter != tmpv.end(); ++iter)
{
curvec.push_back(*iter);
getResult(retvec, hashtable, s, *iter, curvec);
curvec.pop_back(); } }
}; int main(void)
{
string s("aab");
Solution solution;
vector<vector<string>> retvv = solution.partition(s);
vector<vector<string>>::iterator iter;
for(iter = retvv.begin(); iter != retvv.end(); ++iter)
{
vector<string>::iterator it;
for(it = (*iter).begin(); it != (*iter).end(); ++it)
cout<<*it<<" ";
cout<<endl;
} return 0;
}
运行结果:

LeetCode131:Palindrome Partitioning的更多相关文章
- Leetcode131. Palindrome Partitioning分割回文串
给定一个字符串 s,将 s 分割成一些子串,使每个子串都是回文串. 返回 s 所有可能的分割方案. 示例: 输入: "aab" 输出: [ ["aa",&quo ...
- LeetCode 131. 分割回文串(Palindrome Partitioning)
131. 分割回文串 131. Palindrome Partitioning 题目描述 给定一个字符串 s,将 s 分割成一些子串,使每个子串都是回文串. 返回 s 所有可能的分割方案. LeetC ...
- [Swift]LeetCode131. 分割回文串 | Palindrome Partitioning
Given a string s, partition s such that every substring of the partition is a palindrome. Return all ...
- [LeetCode] Palindrome Partitioning II 拆分回文串之二
Given a string s, partition s such that every substring of the partition is a palindrome. Return the ...
- [LeetCode] Palindrome Partitioning 拆分回文串
Given a string s, partition s such that every substring of the partition is a palindrome. Return all ...
- Leetcode: Palindrome Partitioning II
参考:http://www.cppblog.com/wicbnu/archive/2013/03/18/198565.html 我太喜欢用dfs和回溯法了,但是这些暴力的方法加上剪枝之后复杂度依然是很 ...
- LintCode Palindrome Partitioning II
Given a string s, cut s into some substrings such that every substring is a palindrome. Return the m ...
- LeetCode(131)Palindrome Partitioning
题目 Given a string s, partition s such that every substring of the partition is a palindrome. Return ...
- Leetcode 131. Palindrome Partitioning
Given a string s, partition s such that every substring of the partition is a palindrome. Return all ...
随机推荐
- ooofc.com域名备案问题导致无法正常访问临时解决方案
各位尊敬的easyradius用户: 由于临时收到ooofc.coom域名备案被删除的消息,之后ooofc.com就无法访问.导致用户无法访问控制台oa.ooofc.com,及用户中心user.ooo ...
- 关于Unity程序在IOS和Android上显示内嵌网页的方式
近期因为有须要在Unity程序执行在ios或android手机上显示内嵌网页.所以遍从网上搜集了一下相关的资料.整理例如以下: UnityWebCore 从搜索中先看到了这个.下载下来了以后发现这个的 ...
- C#集合--数组
Array类是所有一维和多维数组的隐式基类,同时也是实现标准集合接口的最基本的类型.Array类实现了类型统一,因此它为所有数组提供了一组通用的方法,不论这些数组元素的类型,这些通用的方法均适用. 正 ...
- SQLServer 获得所有表结构(包括表名及字段)
then d.name else null end) 表名, a.colorder 字段序号,a.name 字段名, ( then '√'else '' end) 标识, (case when (SE ...
- U盘FAT32转换NTFS格式
运行----cmd----convert x:/fs:ntfs回车 x标识你的U盘或硬盘盘符 比如你的U盘是H盘,那就是h:/fs:ntfs FAT32----NTFS是不可逆转的转换.
- js apply/call/caller/callee/bind使用方法与区别分析
一.call 方法 调用一个对象的一个方法,以另一个对象替换当前对象(其实就是更改对象的内部指针,即改变对象的this指向的内容). Js代码 call([thisObj[,arg1[, arg2[, ...
- C# 退出程序方法
1.this.Close(); 只是关闭当前窗口,若不是主窗体的话,是无法退出程序的,另外若有托管线程(非主线程),也无法干净地退出: 2.Application.Exit(); 强制所有消息中 ...
- 解决git中文乱码
和linux平台一样,在默认设置下,文件名称中包含中文的文件,在工作区状态输出.查看历史更改概要,以及在补丁文件中,文件名中的中文不能正确的显示,而是用若干八进制字符编码来显示,如下: git sta ...
- MYSQL开发性能研究——INSERT,REPLACE,INSERT-UPDATE性能比较
一.为什么要有这个实验 我们的系统是批处理系统,类似于管道的架构.而各个数据表就是管道的两端,而我们的程序就类似于管道本身.我们所需要做的事情无非就是从A表抽取数据,经过一定过滤.汇总等操作放置到B表 ...
- 使用ECMAscript5中的forEach函数遍历数组
1 var a = [1,2,3]; 2 a.forEach(function(value,index,arr){ 3 arr[index] = value + index; 4 }) 5 conso ...