给定两个整数 n 和 k,返回 1 … n 中所有可能的 k 个数的组合。
示例:
输入: n = 4, k = 2
输出:
[
[2,4],
[3,4],
[2,3],
[1,2],
[1,3],
[1,4],
]
做过了前面关于全排列和组合总和的问题,这道题相比而言就更简单了。对应的回溯法的三大要素:
- 选择列表:当前已经选择的数字
- 可选择列表:当前位置之后的数组元素列表
- 终止条件:当前选择列表的长度等于给定的
k
选择的过程中也不需要额外的剪枝操作,只需要按照一般回溯法的思路解题即可。
Java解题代码:
class Solution {
public List<List<Integer>> combine(int n, int k) {
List<List<Integer>> results = new LinkedList<>();
LinkedList<Integer> track = new LinkedList<>();
int[] nums = new int[n];
for (int i = 0; i < n; i++) {
nums[i] = i + 1;
}
dfs(nums, track, results, k, 0);
results.forEach(System.out :: println);
return results;
}
private void dfs(int[] nums, LinkedList<Integer> track, List<List<Integer>> results, int k, int start) {
if (track.size() == k){
results.add(new LinkedList<>(track));
return;
}
for(int i = start; i < nums.length; i++){
track.add(nums[i]);
dfs(nums, track, results, k, i + 1);
track.removeLast();
}
}
}
Python解题代码:
class Solution:
def combine(self, n: int, k: int) -> List[List[int]]:
if n == 0 or k > n: return []
nums = [i for i in range(1, n + 1)]
results = []
def dfs(track, nums, k):
if len(track) == k:
results.append(track.copy())
return
for i in range(len(nums)):
track.append(nums[i])
dfs(track, nums[i + 1 : ], k)
track.pop()
dfs([], nums, k)
return results