/**
* @author ch080139
* @date 2021/11/24-1:40
* @Description 给定两个整数 n 和 k,返回范围 [1, n] 中所有可能的 k 个数的组合。
*/
public class Solution01 {
public List<List<Integer>> combine(int n, int k) {
List<List<Integer>> result = new ArrayList<>();
List<Integer> temp = new ArrayList<>();
backTracking(n, k, 1, temp, result);
return result;
}
// 从[1, n]中选k个数,当前从start开始选,已经选了的元素放在temp中,已经得到的结果存放在result中
private void backTracking(int n, int k, int start, List<Integer> temp, List<List<Integer>> result) {
if (temp.size() == k) {
result.add(new ArrayList<>(temp));
return;
}
int remainNums = n - start + 1;
int need2Select = k - temp.size();
if(remainNums < need2Select) {
return;
}
for (int i = start; i <= n; i++) {
// 为了体现回溯算法回退的过程,这边写的复杂一些
temp.add(i);
int oldStart = start;
start = i + 1;
backTracking(n, k, start, temp, result);
start = oldStart;
temp.remove(temp.size() - 1);
}
}
}
值得注意
相比于排列问题,组合问题中多了一个start
变量。这是因为不考虑顺序(不同顺序,相同元素看作1种可能)是不能够往回选择的。因为选了1之后是可以选择2的,如果选了2之后再选择1,就会出现重复。所以采用start
标志下一轮能够选择的范围