https://leetcode-cn.com/problems/palindrome-partitioning/
给定一个字符串 s,将 s 分割成一些子串,使每个子串都是回文串。
返回 s 所有可能的分割方案。
示例:
输入: "aab"
输出:
[
["aa","b"],
["a","a","b"]
]
我的算法:假设每个两字母之间都有一个0或者1,表示这两个字母是否相连,然后枚举出所有的0 1,判断相应的字母串是否是回文,很遗憾,这个方法超时 18/22;关键是重复判断了很多不必要的,比如说,如果前面的无法构成回文,后面的就不必要了。
class Solution {
public:
static const int NN=1000;
int AA[NN]={
0
};
int N;
void myinc()
{
int flag=1;
for(int i=N-2;i>-1;i--)
{
if(AA[i]+flag>1)
{
AA[i]=0;
flag=1;
}
else
{
AA[i]+=flag;
break;
}
}
}
bool check(string s)
{
int n=s.length();
for(int i=0;i<n/2;i++)
{
if(s[i]!=s[n-1-i])
return false;
}
return true;
}
bool myexist()
{
for(int i=0;i<N-1;i++)
{
if(AA[i]==0)
return true;
}
return false;
}
vector<vector<string>> partition(string s) {
N=s.length();
vector<vector<string>> res;
if(N==0) return res;
long long LL=pow(2,N-1)-1;
cout<<N<<endl; cout<<LL<<endl;
while(LL>=0)
{
string a=s.substr(0,1);
vector<string> stemp;
AA[N-1]=0;
int i;
for(i=0;i<N;i++)
{
if(AA[i]==1)
{
a+=s[i+1];
}else
{
if(!check(a)) break;
stemp.push_back(a);
a=s.substr(i+1,1);
}
}
if(i==N)
{
//for(int k=0;k<stemp.size();k++)
//cout<<stemp[k]<< " ";
//cout<<endl;
res.push_back(stemp);
}
myinc();
LL--;
}
return res;
}
};
大牛的解法:
class Solution {
public:
vector<string> path;
vector<vector<string>> result;
vector<vector<string>> partition(string s) {
solve(s, 0);
return result;
}
// 检查是否为回文串
bool isPalindrome(const string& s){
int begin = 0, end = s.length() - 1;
while(begin < end){
if(s[begin] != s[end])
return false;
++begin;
--end;
}
return true;
}
// 递归解决
void solve(const string &s,int pos){
if(pos == s.length()){
result.push_back(path);
return;
}
for(int i = pos; i < s.length(); ++i){
string prefix = s.substr(pos, i - pos + 1);//以s[pos]字符开头的所有前缀
if(!isPalindrome(prefix)) //不是回文串就继续找
continue;
path.push_back(prefix); //加入path
solve(s, i + 1); //从已经找到的回文串的下一个字符继续找
path.pop_back(); //记得移除,path还要继续复用
}
}
};