力扣第21天----第216题、第17题
一、第216题–组合总和III
回溯,都可以用树表示。重点在恢复现场
class Solution {
public:
vector<vector<int>> result; //这两个,就是现场
vector<int> path;
void backingtrace(int k, int n, int sum, int startindex){ //更改现场,但是还要递归调用,所以用回溯去恢复现场。
if (sum > n) return; //终止条件,大于n时,跳出去。
if(path.size() == k){ //终止条件,数量等于k时、和等于n时,加入结果。
// cout <<"----------"<<endl;
if (sum == n) result.push_back(path);
return;
}
for(int i = startindex; i <= 9 - (k - path.size()) + 1; i++){ // 设置循环范围
path.push_back(i); //加入元素,同时更改了现场
sum += i;
// cout << i << ' ' << sum << ' ' << n <<endl;
backingtrace(k, n, sum, i+1); //不断地递归调用,直到触发终止条件,即满足题目要求,或者跳出。
sum -= i; //恢复现场
// cout << i << '-' << sum << ' ' << n <<endl;
path.pop_back();
}
}
vector<vector<int>> combinationSum3(int k, int n) {
backingtrace(k, n, 0, 1);
return result;
}
};
二、第17题–电话号码的字母组合
挺有意思的题。string数组,string本身就相当于一个数组,所以string数组是一个二维数组。通过digits的索引找到相应的字母,然后再递归+回溯,提取其中的字母组合。
class Solution {
public:
vector<string> result;
string path;
string letter[10] = {"", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};
void backingtrace(string digits, int index){
if (index == digits.size()){
//cout << index << endl;
result.push_back(path);
return;
}
int digit = digits[index] - '0';
string l = letter[digit];
for(int i = 0; i< l.size(); i++ ){ // 处理 第index个数字
path.push_back(l[i]);
backingtrace(digits, index + 1); // 递归,处理第index + 1个数字
path.pop_back(); // 回溯
}
}
vector<string> letterCombinations(string digits) {
if (digits.size() == 0) return result;
backingtrace(digits, 0);
return result;
}
};