216. Combination Sum III
这个题就是之前二叉树部分的子树节点之和和昨天的那个组合题的结合,把昨天那个题代码改一改就能过; 这个终止条件和carl写的不太一样,标准写法如下:
- 确定终止条件
在上面已经说了,k其实就已经限制树的深度,因为就取k个元素,树再往下深了没有意义。
所以如果path.size() 和 k相等了,就终止。
如果此时path里收集到的元素和(sum) 和targetSum(就是题目描述的n)相同了,就用result收集当前的结果。
所以 终止代码如下:
我写的代码如下,也能通过
class Solution {
public:
vector<vector<int>> result; // 存放符合条件结果的集合
vector<int> path; // 用来存放符合条件单一结果
int sum=0; // k numbers, n is target sum;
void backtracking(int k, int n, int startIndex){
if(sum==n && path.size()==k){
result.push_back(path);
return;
}
for(int i=startIndex;i<=9;i++){
path.push_back(i);
sum+=i;
backtracking(k,n,i+1);
path.pop_back(); //删除尾巴元素 // 回溯,撤销处理的节点
sum-=i;
}
}
vector<vector<int>> combinationSum3(int k, int n) {
backtracking(k,n,1);
return result;
}
};
17. Letter Combinations of a Phone Number
这个题记住输入的digits的长度就是树的深度;这个题和前面几个题的区别是这是在几个不同的集合里面取元素,前面的题目都是在同一个集合里面取几个元素出来;所以这个题不需要index来指向同一个集合的不同位置,只需要index指向输入digits记住树遍历到第几层了;
class Solution {
public:
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 s; //这个用来存单个的结果集
void backtracking(const string& digits, int index){ //这个二叉树的深度就是index的个数,宽度就是三个字母
if(index ==digits.size()){
result.push_back(s);//如果遍历到了深度就存进去;
return;
}
int digit = digits[index] - '0'; // 将index指向的数字转为int,digits是输入的字符串, 比如2345
string letters = letterMap[digit]; // 取数字对应的字符集,这里取出来了一个数字对应的字母
for(int i=0; i<letters.size();i++){
s.push_back(letters[i]);
backtracking(digits,index+1);
s.pop_back(); //这种回溯算法都是先走完一条边,然后再走for循环往右边走;
}
}
vector<string> letterCombinations(string digits) {
if(digits.size()==0)
return result;
backtracking(digits,0);
return result;
}
};