回溯理论
什么是回溯
回溯,顾名思义,返回溯源,记录当前节点后返回前一节点继续的过程。本质上是一种罗列所有情况的穷举搜索。
递归
递归,函数间接或者直接调用自身,回到最初最简单的情况。目前的情况归根结底就是一棵树的情况。
回溯与递归
为什么说回溯常常伴随递归?递归是把一棵大二叉树返回到一个最基本的三个节点的树,在每一次树变小的过程中,都有一个数的子树返回根节点的过程。
n个数中k个数的组合
问题
1.返回值问题:返回值必须与返回类型相匹配(-1)
2.私有成员变量的作用域问题
核心代码模式下,不管声明为private、public还是protected,都属于类内,所以可以访问。
private:类内访问;
protected:类内和派生类访问;
public:类内、派生类和类外都可以访问。

代码
class Solution {
private:
vector<int> vec;
vector<vector<int>> res;
public:
void backTrack(int n, int k, int startIndex) {
if (vec.size() == k) {
res.push_back(vec);
return;
}
for (int i = startIndex; i <= n-(k-vec.size()+1); i++) {
vec.push_back(i);
backTrack(n, k, i + 1);
vec.pop_back();
}
}
vector<vector<int>> combine(int n, int k) {
backTrack(n, k, 1);
return res;
}
};
总结
组合相当于把K层循环的过程用递归来实现。树的宽度要遍历的数组中的每一个元素,是循环的第一层。
k个不相同数相加为n的组合
思路
1.递归函数的返回值和参数
返回值是void类型,参数是传入的n与k。以及用sum记录当前的和。
2.终止条件
相加为n且是k个数;
3.单层递归的逻辑
一层循环下面,每次sum+i,压入;
回溯过程和处理过程一一对应。
代码
class Solution {
public:
vector<int> path;
vector<vector<int>> res;
void backtrack(int n, int k,int sum, int startIndex) {
if (sum == n&&path.size()==k) {
res.push_back(path);
return;
}
for (int i = startIndex; i <= 9; i++) {
sum += i;
path.push_back(i);
backtrack(n, k, sum, i + 1);
sum -= i;
path.pop_back();
}
}
vector<vector<int>> combinationSum3(int k, int n) {
int sum=0;
backtrack(n,k,sum,1);
return res;
}
};
电话键有限数字对应的字母组合
思路
1.建立数字与字母的映射关系;const string lettermap[10]={,,}
2.树的宽度与递归的深度;
3.回溯过程
结果用一个字符串string s和一个字符串数组vector
<1>确定返回值(void)和参数(digits,int index);
<2>确定终止条件:string的长度和digit的长度相等;digits.size()==index
<3>单层循环逻辑
压入--遍历--弹出
代码
class Solution {
public:
vector<string> res;
string path;
const string lettermap[10] = {",", ",", "abc", "def", "ghi",
"jkl", "mno", "pqrs", "tuv", "wxyz"};
void backTrack(string&digits, int index) {
if (index == digits.size()) {
res.push_back(path);
return;
}
// 建立数字--字母映射
int digit = digits[index] - '0'; // 把字符类型转化为int;
string letters = lettermap[digit]; // 建立数字和字母的对应关系;
for (int i = 0; i <letters.size() ; i++) {
path.push_back(letters[i]);
backTrack(digits, index + 1);
path.pop_back();
}
}
vector<string> letterCombinations(string digits) {
backTrack(digits, 0);
return res;
}
};
浙公网安备 33010602011771号