刚刚接触回溯有点懵逼,发现手写一遍思路会清晰很多。
题目链接在这里:分割回文串
废话不多说,直接看手推:
看懂递归的过程很容易写出如下代码:
主要代码如下:
class Solution {
public:
vector<vector<string>> result;
vector<string> path;
void backtracking(const string & s, int startIndex){
// s代表输入的字符串
// 终止条件
if(startIndex >= s.size()){
result.push_back(path);
return;
}
for(int i = startIndex; i<s.size(); i++){
// 判断是否是回文字符
if(isPalidrome(s, startIndex, i)){ // 如果是回文字符串:加入path
// 从startIndex开始到结尾的子串
// 比如“abcd”, 当startIndex为0时候:for循环有三次:"a", "ab", "abc", "abcd"。
// 这里回顾一下string容器中的子串操作函数:substr(int pos = 0, int n = pos) const;
// 返回由pos开始的n个字符组成的字符串(注意n是获取字符串个数)如下操作
// 获取[startIndex, i]的字符串
string str = s.substr(startIndex, i - startIndex + 1);
path.push_back(str);
//
}else{
// 如果不是,结束本次循环,直接continue
continue;
}
// 递归,选择了i+1为起始位置的子串>比如:这时候startIndex为1:
// 进入递归下一层的for循环就是从1-2子串:"b", "bc", "bcd"这三个情况判断
// 这里建议手推一遍
backtracking(s, i + 1);
path.pop_back(); // 这里要回溯
}
}
// 判断是否是回文字符串的函数
bool isPalidrome(const string& s, int start, int end){
// start开头字符, end结尾字符
// 这个就是双指针法,同时从头和尾巴出进行比较,直到左指针等于或者大于右指针
for(int i = start, j = end; i<j; i++, j--){
if(s[i] != s[j]){
return false;
}
}
return true;
}
vector<vector<string>> partition(string s) {
result.clear();
path.clear();
backtracking(s, 0);
return result;
}
};