LC 216.组合总和III
题目链接:LC 216.组合总和III
思路:k个数相加等于n,这k个数不能重复且只能从1到9中选,返回的是满足条件的所有k个数组成的vector。本题思路和 77.组合相同,k为二叉树深度,从i到9(i从1到9取值)为二叉树的孩子个数,进行递归。
需要注意的是,本题可以进行剪枝,当遍历的路径之和大于n时,就没必要再向下遍历了。
也可以将sum在递归中传入,回溯的时候也要对sum进行回溯。
代码:
class Solution {
public:
vector<int> path;
vector<vector<int>> result;
void backtracking(int begin, int k, int n){
//剪枝操作
int s = 0;
for(int j: path){
s += j;
}
if(s>n)return;
//终止条件:当长度为k,就返回
//返回前判断path之和是否是n,若是n就保存结果,否则直接返回
if(path.size()==k){
int sum = 0;
for(int i : path){
sum += i;
}
if(sum==n){
result.push_back(path);
}
return;
}
//若还没到k个
for(int i=begin; i<=9; i++){
path.push_back(i);
backtracking(i+1, k, n);
path.pop_back();
}
}
vector<vector<int>> combinationSum3(int k, int n) {
backtracking(1, k, n);
return result;
}
};
LC 17.电话号码的字母组合
题目链接:LC 17.电话号码的字母组合
思路:用map将每个数字对应的字符串保存起来,按照输入的字符串(数字)进行递归遍历,递归的深度就是数字串的长度,每次递归的宽度就是数字对应的字符串长度。
代码:
class Solution {
public:
//用string数组来代替map,从0到9
//因为题干说明只输入2到9,所以可以用数组来代替map
string map[10] = {
"",//0
"",//1
"abc",//2
"def",
"ghi",
"jkl",
"mno",
"pqrs",
"tuv",
"wxyz",
};
vector<string> result;
string s;
//回溯
void backtracking(int index, string digits){
//当遍历到digits最后就直接返回
if(index==digits.size()){
result.push_back(s);
return;
}
//不然就遍历cur对应的map
int id = digits[index]-'0';
string letter = map[id];
for(int i=0; i<letter.size(); i++){
s.push_back(letter[i]);
backtracking(index+1, digits);
s.pop_back();
}
}
vector<string> letterCombinations(string digits) {
if(digits.size()==0)return result;
backtracking(0, digits);
return result;
}
};