216.组合总和III
卡哥建议:如果把 组合问题理解了,本题就容易一些了。
题目链接/文章讲解:https://programmercarl.com/0216.%E7%BB%84%E5%90%88%E6%80%BB%E5%92%8CIII.html
视频讲解:https://www.bilibili.com/video/BV1wg411873x做题思路:
本题k相当于树的深度,9(因为整个集合就是9个数)就是树的宽度。
例如 k = 2,n = 4的话,就是在集合[1,2,3,4,5,6,7,8,9]中求 k(个数) = 2, n(和) = 4的组合。
选取过程如图:
图中,可以看出,只有最后取到集合(1,3)和为4 符合条件。
回溯三部曲看卡哥文章吧。
剪枝优化:
1,已选元素总和如果已经大于n(图中数值为4)了,那么往后遍历就没有意义了,直接剪掉。
2,for循环的范围也可以剪枝,i <= 9 - (k - path.size()) + 1就可以了,和昨天的题一样
本题代码:
1 class Solution { 2 private: 3 vector<vector<int>> result; // 存放结果集 4 vector<int> path; // 符合条件的结果 5 void backtracking(int targetSum, int k, int sum, int startIndex) { 6 if (sum > targetSum) { // 剪枝操作 7 return; // 如果path.size() == k 但sum != targetSum 直接返回 8 } 9 if (path.size() == k) { 10 if (sum == targetSum) result.push_back(path); 11 return; 12 } 13 for (int i = startIndex; i <= 9 - (k - path.size()) + 1; i++) { // 剪枝 14 sum += i; // 处理 15 path.push_back(i); // 处理 16 backtracking(targetSum, k, sum, i + 1); // 注意i+1调整startIndex 17 sum -= i; // 回溯 18 path.pop_back(); // 回溯 19 } 20 } 21 22 public: 23 vector<vector<int>> combinationSum3(int k, int n) { 24 result.clear(); // 可以不加 25 path.clear(); // 可以不加 26 backtracking(n, k, 0, 1); 27 return result; 28 } 29 };
17.电话号码的字母组合
卡哥建议:本题大家刚开始做会有点难度,先自己思考20min,没思路就直接看题解。
题目链接/文章讲解:https://programmercarl.com/0017.%E7%94%B5%E8%AF%9D%E5%8F%B7%E7%A0%81%E7%9A%84%E5%AD%97%E6%AF%8D%E7%BB%84%E5%90%88.html
视频讲解:https://www.bilibili.com/video/BV1yV4y1V7Ug做题思路:
电话按键上2~9数字上对应着3个或4个字母,题目求的是输入数字,输出字母的组合,可以使用map或者定义一个二维数组,例如:string letterMap[10][],来做映射,10行,4列的二维数组,代码见卡哥文章。
图中可以看出遍历的深度,就是输入"23"的长度,而叶子节点就是我们要收集的结果,输出["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"]。
需要一个字符串s来收集叶子节点的结果,然后用一个字符串数组result保存起来, 代码中的 index 是从0开始的,是记录遍历第几个数字了,就是用来遍历digits的(题目中给出数字字符串“23”),就是下标,同时index也表示树的深度。本题代码:
1 class Solution { 2 private: 3 const string letterMap[10] = { //二维数组,10行,列并没有定义,但能看出来 4 "", // 0 5 "", // 1 6 "abc", // 2 7 "def", // 3 8 "ghi", // 4 9 "jkl", // 5 10 "mno", // 6 11 "pqrs", // 7 12 "tuv", // 8 13 "wxyz", // 9 14 }; 15 public: 16 vector<string> result;//放叶子节点的结果 17 string s; 18 void backtracking(const string& digits, int index) { 19 if (index == digits.size()) { 20 result.push_back(s); 21 return; 22 } 23 int digit = digits[index] - '0'; // 将index指向的数字转为int,比如digits[0]="2",减完后,就是2了 24 string letters = letterMap[digit]; // 取数字对应的字符集,比如,letterMap[2]="abc",然后在二维数组里就能找到对应的字符串 25 for (int i = 0; i < letters.size(); i++) { //树的结构,看上图 26 s.push_back(letters[i]); // 处理 27 backtracking(digits, index + 1); // 递归,注意index+1,一下层要处理下一个数字了 28 s.pop_back(); // 回溯 29 } 30 } 31 vector<string> letterCombinations(string digits) { 32 s.clear(); 33 result.clear(); 34 if (digits.size() == 0) { 35 return result; 36 } 37 backtracking(digits, 0); 38 return result; 39 } 40 };
标签:216,digits,return,string,index,int,随想录,result,字母组合 From: https://www.cnblogs.com/romantichuaner/p/17646828.html