回溯是一种算法思想,递归是一种编程方法。
回溯方法整体思路:搜索每一条路,每次回溯是对具体的一条路径而言的。
对当前搜索路径下的未探索区域进行搜索,则可能有两种情况:
1、当前未搜索区域满足结束条件,则保存当前路径并退出当前搜索;
2、当前未搜索区域需要继续搜索,则遍历当前所有可能的选择;如果该选择符合要求,则把当前选择加入当前的搜索路径中,并继续搜索新的未搜索区域。
一般回溯用在需要保存所有情况的题中,也就是不是计算有多少符合条件的情况。
substr这个函数:substr(start, length)方法:返回一个从指定位置开始,并具有指定长度的子字符串。length可以不写默认就是i这个位置后面所有的数字
模板1
res = []
path = []
def backtrack(未探索区域, res, path):
if 未探索区域满足结束条件:
res.add(path) # 深度拷贝
return
for 选择 in 未探索区域当前可能的选择:
if 当前选择符合要求:
path.add(当前选择)
backtrack(新的未探索区域, res, path)
path.pop()
力扣131分割回文串 中等
输入 s = "aab"
输出 [["a","a","b"],["aa","b"]]
还是在递归前后push pop
class Solution {
public:
vector<vector<string>> partition(string s) {
vector<vector<string>> res;
backtrack(s, res, {});
return res;
}
void backtrack(string s, vector<vector<string>>& res, vector<string> path) {
if (s.size() == 0) {
res.push_back(path);
return;
}
for (int i = 1; i <= s.size(); i++) {
string pre = s.substr(0, i);
if (isPalindrome(pre)) {
path.push_back(pre);
backtrack(s.substr(i), res, path);
path.pop_back();
}
}
}
bool isPalindrome(string s) {
if (s.size() == 0) return true;
int start = 0, end = s.size() - 1;
while (start <= end) {
if (s[start] != s[end])
return false;
start ++;
end --;
}
return true;
}
};