1.描述
Give a string, you can choose to split the string after one character or two adjacent characters, and make the string to be composed of only one character or two characters. Output all possible results.
样例
Given the string "123"
return [["1","2","3"],["12","3"],["1","23"]]
2.分析
给一个字符串,你可以选择在一个字符或两个相邻的字符之后拆分字符串,并使该字符串仅由一个字符或两个字符组成。输出所有可能的结果。
其实这道题最难的地方在于看懂英文题目(笑)。上面就是问题的翻译,其实根据样例也可以看出,就是把给定的字符串分解成很多小串,每个小子串由一个或两个字符组成。事实上当给定一个长度大于2的子串如1234时,第一种情况把该字符串分为1和后面的234,234分解后把1加入其中。另一种情况是把1234分为12和34,12作为一个整体,34分解后的子串再和12组合,两种情况加起来即为1234分解的情况。
3.代码
class Solution {
public:
/*
* @param : a string to be split
* @return: all possible split string array
*/
vector<vector<string> > digui(string s)
{
//cout<<s<<endl<<endl;
if(s.size()<=2)//2或1
{
vector<string> v2;
vector<vector<string> > v3;
v2.push_back(s);
v3.push_back(v2);
if(s.size()==2)
{
vector<string> v1;
v1.push_back(s.substr(0,1));
v1.push_back(s.substr(1,1));
v3.push_back(v1);
}
return v3;
}
if(s.size()>=2)
{
string a=s.substr(0,1);
string b=s.substr(1);
vector<vector<string> > B=digui(b);//得到b串分解后得大vector
for(int i=0;i<B.size();i++)
{
B[i].insert(B[i].begin(),a);
}
string c=s.substr(0,2);
string d=s.substr(2);
vector<vector<string> > C=digui(d);
for(int j=0;j<C.size();j++)
{
C[j].insert(C[j].begin(),c);
}
B.insert(B.end(),C.begin(),C.end());
return B;
}
}
vector<vector<string>> splitString(string& s) {
// write your code here
if(s.size()<2)
{
vector<string> v1;
if(s.size()==1)
v1.push_back(s);
vector<vector<string> >v2;
v2.push_back(v1);
return v2;
}
return digui(s);
}
};
4.总结
递归的出口设置在要处理的子串长度为1或2,若长度大于2,则把当前子串分别以取前一位和前两位区别为两种情况,分解后得到的缩小长度后的子串再次分解,分解后加入之前去掉的前两位合起来为该长串的分解。这里红色代码向vector中添加元素之所以没有用push_back而是insert,是因为push_back只能查到vector的尾部,这样做下来得到的分解并不一定是按照原字符串中的顺序,加入排序后得到的分解结果还是按照字符在字符串中出现的顺序排列的。
另外在digui函数中设置字符串的长度小于2时为出口,之所以在splitSrting函数中还要判断字符串小于2的情况,看似多此一举,其实是对于一种特殊情况的考虑。当给出的字符串为" "时,假如没有splitString中的特殊情况处理,直接调用digui函数得到的输出为[[" "]],实际上需要得到的正确答案为[[ ]]。