心得:
216这道题大体上和77类似,就是需要多设置一个sum的数来计算元素和是否达到要求。
因此这种计算元素总和的题目都可以设置这样一个sum。
此外,因为这个sum需要在每一次的递归中更新,所以需要写到递归函数的参数里。这也是确定递归的第一步!!!!
最后这道题的终止条件也有讲究,同时满足两个条件就会放入结果集,但满足前一个同样会return终止。因为后面要pop要腾出空间再试试别的元素。
第一题、组合总和-3 LeetCode216 https://leetcode.cn/problems/combination-sum-iii/
给定一个n和k,给出一个不重复的k个1-9的数,和为n。
心得里面也说了,设置一个sum并且递归函数的参数要有它。
此外也要注意,给定的函数和自己递归函数参数顺序的问题。
终止条件也有讲究,同时满足两个条件就会放入结果集,但满足前一个同样会return终止。因为后面要pop要腾出空间再试试别的元素。
剪枝过程:sum已经大于目标值的话,可以直接return。 此外,for里面遍历到最后几个数(起始位置距离9太近(小于k)也没必要。
class Solution {
public:
vector<vector<int>> res;
vector<int> path;
int sum = 0;
void backtracking(int n, int k, int sum, int startIndex){
//if(path.size() == k && sum == n){
if(path.size() == k){
if(sum == n) res.push_back(path);
return;// 如果path.size() == k 但sum != targetSum 直接返回
}
for(int i = startIndex; i <= 9; i++){
sum += i;//处理
path.push_back(i);//处理
backtracking(n, k, sum, i + 1);
sum -= i;//回溯
path.pop_back();//回溯
}
return;
}
vector<vector<int>> combinationSum3(int k, int n) {
res.clear();
path.clear();
//backtracking(k, n, 0, 1);
backtracking(n, k, 0, 1);
return res;
}
};
第二题、电话号码的组合 LeetCode17 https://leetcode.cn/problems/letter-combinations-of-a-phone-number/
数字和字母如何映射
可以使用map或者定义一个二维数组,例如:string letterMap[10],来做映射,我这里定义一个二维数组,代码如下:
const string letterMap[10] = {
"", // 0
"", // 1
"abc", // 2
"def", // 3
"ghi", // 4
"jkl", // 5
"mno", // 6
"pqrs", // 7
"tuv", // 8
"wxyz", // 9
};
这道题不同于前两道题,是从不同的集合里面匹配元素,所以不需要用startindex来控制元素不重复,用一个index来表明遍历到哪个数字就可以了。
class Solution {
public:
const string letterMap[10]{
"", //0
"", //1
"abc",
"def",
"ghi",
"jkl",
"mno",
"pqrs",
"tuv",
"wxyz", //9
};
vector<string> res;
string str;
void backtracking(const string& digits, int index){
if(index == digits.size()){
res.push_back(str);
return;
}
int digit = digits[index] - '0'; // 将index指向的数字转为int
string letters = letterMap[digit]; // 取数字对应的字符集
for(int i = 0; i < letters.size(); i++){
str.push_back(letters[i]);
backtracking(digits, index + 1);
str.pop_back();
}
return;
}
vector<string> letterCombinations(string digits) {
res.clear();
str.clear();
if (digits.size() == 0) {
return res;//处理空集的情况
}
backtracking(digits, 0);
return res;
}
};