1. 题目描述
Given two integers n and k, return all possible combinations of k numbers out of 1 … n.
For example,
If n = 4 and k = 2, a solution is:[
[2,4],
[3,4],
[2,3],
[1,2],
[1,3],
[1,4],
]
2. 解题思路
这个问题可以很容易的与背包问题联系起来, 限制条件是,背包里面只能放两个元素, 还是可以使用DFS 处理
3. code
class Solution {
public:
vector<vector<int>> combine(int n, int k) {
search(n, 0, 0, k);
return res;
}
private:
vector<vector<int>> res;
vector<int> path;
void search(int n, int depth, int cur_num, int k){
if (cur_num == k){
res.push_back(path);
return;
}
if (depth == n){
return;
}
search(n, depth + 1, cur_num, k);
path.push_back(depth + 1);
search(n, depth + 1, cur_num + 1, k);
path.pop_back();
}
};
4. 大神解法
个人感觉, 这只是回溯解法的另一个版本的解释
/*
Basically, this solution follows the idea of the mathematical formula C(n,k)=C(n-1,k-1)+C(n-1,k).
Here C(n,k) is divided into two situations. Situation one, number n is selected, so we only need to select k-1 from n-1 next. Situation two, number n is not selected, and the rest job is selecting k from n-1.
*/
public class Solution {
public List<List<Integer>> combine(int n, int k) {
if (k == n || k == 0) {
List<Integer> row = new LinkedList<>();
for (int i = 1; i <= k; ++i) {
row.add(i);
}
return new LinkedList<>(Arrays.asList(row));
}
List<List<Integer>> result = this.combine(n - 1, k - 1);
result.forEach(e -> e.add(n));
result.addAll(this.combine(n - 1, k));
return result;
}
}