77.组合回溯 1.理解递归和回溯之间的关系 2.简化算法需要考虑剪支 3.是否返回值需要根据情况进行判断
非剪支版本
class Solution {
public:
vector<vector<int>> result;//全局变量,用于存储combine的结果
vector<int> tmp;//用于存储临时结果
//不需要返回值,所以设置递归函数为
void recount(int n,int k,int index){
//递归返回情况
if(tmp.size()==k){
result.push_back(tmp);
return;//当tmp中存储k个数时,即可返回
}
//采用循环处理
for(int i=index;i<=n;i++){
//将第i个元素存入tmp当中
tmp.push_back(i);
//执行递归
recount(n,k,i+1);
//回溯
tmp.pop_back();
}
}
vector<vector<int>> combine(int n, int k) {
//采用递归方法,不断进行回溯递归
int index=1;//统计开始时的下标
recount(n,k,index);
return result;
}
};
剪支版本
class Solution {
public:
vector<vector<int>> result;//全局变量,用于存储combine的结果
vector<int> tmp;//用于存储临时结果
//不需要返回值,所以设置递归函数为
void recount(int n,int k,int index){
//递归返回情况
if(tmp.size()==k){
result.push_back(tmp);
return;//当tmp中存储k个数时,即可返回
}
//采用循环处理
for(int i=index;i<=n-(k-tmp.size())+1;i++){//此处进行了剪支
//将第i个元素存入tmp当中
tmp.push_back(i);
//执行递归
recount(n,k,i+1);
//回溯
tmp.pop_back();
}
}
vector<vector<int>> combine(int n, int k) {
//采用递归方法,不断进行回溯递归
int index=1;//统计开始时的下标
recount(n,k,index);
return result;
}
};
216 组合综合三 1.需要注意,在执行递归传入的参数时什么,不是index,是当前的i!!! 2.剪支需要思考特殊的条件
class Solution {
private:
vector<vector<int>> result;//用于存储组合总和结果
vector<int> tmp;//用于存储临时组合
int combinesum=0;//记录组合数之和
//采用递归三部法设计递归函数
void travelsum(int k,int n,int index){//index指向递归开始的数据下标
//递归终止条件
if(tmp.size()==k){//满足k个数时
//再次判断是否满足和等于n
if(combinesum==n)
result.push_back(tmp);
return;
}
//剪支
if(combinesum>n){
return;
}
//单层递归逻辑
for(int i=index;i<=9;i++){
tmp.push_back(i);
combinesum=combinesum+i;
travelsum(k,n,i+1);
//回溯
combinesum=combinesum-i;
tmp.pop_back();
}
return;
}
public:
vector<vector<int>> combinationSum3(int k, int n) {
result.clear();
tmp.clear();
travelsum(k,n,1);
return result;
}
};
17.电话号码的字母组合 参考上述两题,需要注意的是i的取值范围变化
class Solution {
private:
//设置数字和字母对应的二维映射
const string letterMap[10] = {
"", // 0
"", // 1
"abc", // 2
"def", // 3
"ghi", // 4
"jkl", // 5
"mno", // 6
"pqrs", // 7
"tuv", // 8
"wxyz", // 9
};
//在之前组合数字的基础上进行改进
vector<string> result;//用于存储最后结果
string cur;//存储单次递归的结果
void combinletter(string digits,int index){
//递归终止条件
if(cur.size()==digits.size()){
result.push_back(cur);
return;
}
int digit = digits[index] - '0'; // 将index指向的数字转为int
string letters = letterMap[digit];
//执行单层递归
for(int i=0;i<letters.size();i++){//在index所指的数字所能代表的字母中取值
cur.push_back(letters[i]);
combinletter(digits,index+1);
cur.pop_back();
}
return;
}
public:
vector<string> letterCombinations(string digits) {
result.clear();
cur.clear();
combinletter(digits,0);
return result;
}
};