给定一个字符串s
,将 s
分割成一些子串,使每个子串都是回文串 。返回 s
所有可能的分割方案。
切割问题也可以抽象为一棵树形结构图,如下图所示:
递归用来纵向遍历,for循环用来横向遍历,切割线切割到字符串的末尾位置。
回溯三部曲:
(1)确定参数和返回值:一维数组存放单一结果,二维数组存放最终结果,参数需要start,因为不能重复切割。
(2)终止条件:起始位置大于等于字符串的大小,保存结果并返回。
(3)单层搜索的逻辑:收集单一结果。
实现代码如下:
//分割回文串
vector<string> vec;
vector<vector<string>> result;
bool isPalindrome(string &s, int start, int end) {
for(int i = start, j = end; i<=j; i++, j--) {
if(s[i] != s[j]) {
return false;
}
}
return true;
}
void backtracking(string &s, int start) {
//确定终止条件 判断回文的逻辑放在后面
if(start >= s.size()) {
result.push_back(vec);
return;
}
//单层搜索的逻辑
for (int i = start; i< s.size(); i++) {
//子串的范围就是[start,i]
if (isPalindrome(s, start, i)) {
string str = s.substr(start, i-start+1);
vec.push_back(str);
}
else {
continue;
}
backtracking(s, i+1); //递归
vec.pop_back(); //回溯
}
}
vector<vector<string>> partition(string s) {
vec.clear();
result.clear();
backtracking(s,0);
return result;
}