216. 组合总和 III
找出所有相加之和为 n
的 k
个数的组合,且满足下列条件:
- 只使用数字1到9
- 每个数字 最多使用一次
返回 所有可能的有效组合的列表 。该列表不能包含相同的组合两次,组合可以以任何顺序返回。
思路:按照组合的方法,终止条件增加一个数组和的判断即可。
可以做剪枝,当现有路径和超过目标和时就可以停止。
class Solution {
public:
vector<vector<int>> result;
vector<int> path;
void backtracking(int k,int targetsum,int sum,int startIndex){
//剪枝
if(sum>targetsum){
return;
}
if(path.size()==k){
if(sum==targetsum){
result.push_back(path);
}
return ;
}
for(int i=startIndex;i<=9;i++){
sum+=i;
path.push_back(i);
backtracking(k,targetsum,sum,i+1);
path.pop_back();
sum-=i;
}
}
vector<vector<int>> combinationSum3(int k, int n) {
backtracking(k,n,0,1);
return result;
}
};
17. 电话号码的字母组合
给定一个仅包含数字 2-9
的字符串,返回所有它能表示的字母组合。答案可以按 任意顺序 返回。
给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。
思路:该问题主要是要解决数字与字母的映射以及不定个数的for循环遍历。没有想到怎么用回溯去解决这个问题。看到题解才明白。主要是使用给定字符串索引作为回溯的参数,实现n次循环。
注意字母和数字映射建立的字符串数组实现写法!
class Solution {
public:
vector<string> result;
string character[10]={"","","abc","def", "ghi","jkl", "mno","pqrs","tuv", "wxyz"};
string str="";
void backtracking(string digits,int index){
if(index==digits.size()){
if(str!="") result.push_back(str); //不加入空字符串
return;
}
int num=digits[index]-'0'; //获取digits中数字
for(int i=0;i<character[num].size();i++){
str.push_back(character[num][i]);
backtracking(digits,index+1);
str.pop_back();
}
}
vector<string> letterCombinations(string digits) {
backtracking(digits,0);
return result;
}
};
总结:回溯算法用于解决组合问题主要是解决n次循环问题,注意设定好索引作为回溯函数的参数。