一、组合总和Ⅲ-LeetCode 216
Leecode链接: leetcode 216
文章链接: 代码随想录
视频链接: B站
找出所有相加之和为 n 的 k 个数的组合,且满足下列条件:
只使用数字1到9
每个数字 最多使用一次
返回 所有可能的有效组合的列表 。该列表不能包含相同的组合两次,组合可以以任何顺序返回。
示例1:
输入: k = 3, n = 7
输出: [[1,2,4]]
解释:
1 + 2 + 4 = 7
没有其他符合的组合了。
思路
与组合总和类似,只不过递归的退出条件改变为path中数目为k个数且总和为n。
实现代码
//cpp
class Solution {
public:
vector<int>path;
vector<vector<int>> res;
void combina(int target,int sum,int k,int index){
if(k==path.size()){
if(sum==target){
res.push_back(path);
}
return;
}
for(int i = index;i<=9;i++){
sum += i;
path.push_back(i);
combina(target,sum,k,i+1);
sum -=i;
path.pop_back();
}
}
vector<vector<int>> combinationSum3(int k, int n) {
combina(n,0,k,1);
return res;
}
};
问题
无。
二、电话号码的字母组合-LeetCode 17
Leecode链接: LeetCode 17
文章链接: 代码随想录
视频链接: B站
给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。答案可以按 任意顺序 返回。
给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。
示例1:
输入:digits = "23"
输出:["ad","ae","af","bd","be","bf","cd","ce","cf"]
思路
思路很简单,首先将数字与字母做好映射,然后根据digits字符串开始遍历映射好的数组。遍历前取出对应的字符串,后面的操作与上一题类似。
实现代码
//cpp
class Solution {
private:
const string letterMap[10] = {
"", // 0
"", // 1
"abc", // 2
"def", // 3
"ghi", // 4
"jkl", // 5
"mno", // 6
"pqrs", // 7
"tuv", // 8
"wxyz", // 9
};
public:
vector<string> result;
string s;
void backtracking(const string& digits, int index) {
if (s.size() == digits.size()) {
result.push_back(s);
return;
}
int digit = digits[index] - '0'; // 将index指向的数字转为int
string letters = letterMap[digit]; // 取对应的字符集
for (int i = 0; i < letters.size(); i++) {
s.push_back(letters[i]); // 处理
backtracking(digits, index + 1); // 递归,注意index+1,一下层要处理下一个数字了
s.pop_back(); // 回溯
}
}
vector<string> letterCombinations(string digits) {
s.clear();
result.clear();
if (digits.size() == 0) {
return result;
}
backtracking(digits, 0);
return result;
}
};
问题
解题思路没有问题,但在实现代码时,把取出字符串这步操作写成了一个for循环,导致有两个for循环嵌套。以示例数据为例,出现了[“ad”,“ae”,“af”,“bd”,“be”,“bf”,“cd”,“ce”,“cf”,“dd”,“de”,“df”,“ed”,“ee”,“ef”,“fd”,“fe”,“ff”]的结果。