77 组合
题目
给定两个整数 n 和 k,返回 1 … n 中所有可能的 k 个数的组合。
思路
用循环的思路考虑,如果n=4,k=2,则两次循环,外循环i从1~4,内循环为i+1- - -4, k为多少就需要进行多少次循环。递归的思路与循环的思路类似,每次递归嵌套一个for循环,k次递归就相当于进行了k次循环。
代码
class Solution {
public:
vector<int> path;
vector<vector<int>> res;
void back(int n,int k,int index) {
if(path.size() == k) {
res.push_back(path);
return;
}
for(int i = index;i <= n - (k - path.size()) + 1;i++) {
path.push_back(i);
back(n,k,i + 1);
path.pop_back();
}
}
vector<vector<int>> combine(int n, int k) {
back(n,k,1);
return res;
}
};
216 组合总和Ⅲ
思路
从1~9中找k个数,和为n,且组合中不存在重复的数字。递归退出的条件为当前组合的size为k,且组合的和为n。与上题类似,只是增加了限制条件 和为n,可以用sum来统计当前和,从当前元素的下一个元素递归搜索(这样保证组合中元素不重复),满足条件时加入结果数组。
代码
class Solution {
public:
vector<vector<int>> res;
vector<int> comb;
int sum;
void backTracking(int k,int n,int index) {
if(comb.size() == k && sum == n) {
res.push_back(comb);
return;
}
for(int i = index;i <= 9 && sum + i <= n;i++) {
sum += i;
comb.push_back(i);
backTracking(k,n,i + 1);
sum -= i;
comb.pop_back();
}
}
vector<vector<int>> combinationSum3(int k, int n) {
backTracking(k,n,1);
return res;
}
};
17 电话号码的字母组合
题目
给定一个仅包含数字 2-9 的字符串digits,返回所有它能表示的字母组合。
思路
此题相当于是在digits.size()个集合中进行组合。用index来表示当前访问第几个集合。递归的终止条件就是index == digits.size()时,说明字符串中的每个数字都已经组合过了,返回即可。与上题不同的是,递归是从给定字符串的下一个数字开始,而for循环是遍历当前数字所能表示的字符,是两个不同的对象。
代码
class Solution {
public:
vector<string> key{"_","!@#","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};
vector<string> res;
string path;
void backTracking(string digits,int index) {
if(index == digits.size()) {
res.push_back(path);
return;
}
int num = digits[index] - '0';
for(int i = 0;i < key[num].size();i++) {
path += key[num][i];
backTracking(digits,index + 1);
path.pop_back();
}
}
vector<string> letterCombinations(string digits) {
if(digits.size() == 0)
return res;
backTracking(digits,0);
return res;
}
};