给定两个整数 n
和 k
,返回范围 [1, n]
中所有可能的 k
个数的组合。
你可以按 任何顺序 返回答案。
示例 1:
输入:n = 4, k = 2 输出: [ [2,4], [3,4], [2,3], [1,2], [1,3], [1,4], ]
示例 2:
输入:n = 1, k = 1 输出:[[1]]
提示:
1 <= n <= 20
1 <= k <= n
思路:
组合问题,可以采用递归 + 回溯方法。用 List<Integer> path 来记录每一组结果,当 path 中的节点数目达到 k 时将 path 放进 result 数组,然后进行回溯,使得 path 里面的节点又变少,从而可以去递归添加其他符合要求的节点。通过递归实现向下遍历(k 为向下遍历的深度),通过 for 循环实现横向遍历(n 为横向遍历的宽度)。
- 不需要返回值。递归的参数是 n, k, startIndex。startIndex 是用来标识每次递归从哪个数开始添加进 path 。
- 递归的终止条件是 path.size() == k , 将 path 添加进 result 数组里面,返回;
- 单层处理逻辑:进行一个 for 循环,将没添加进 path 的数依次添加进 path 里面相同的下标(依赖回溯)。对于每一个已经添加进 path 的数,递归寻找比这个数大的数添加进 path 数组里面(为了避免重复),直到 path 里面的数的个数等于 k。
代码:
class Solution {
public List<List<Integer>> result = new ArrayList<>();
public List<Integer> path = new LinkedList<>();
public List<List<Integer>> combine(int n, int k) {
backTracking(n,k,1);
return result;
}
public void backTracking(int n,int k,int startIndex){
if(path.size()==k){
result.add(new ArrayList(path));
return;
}
for(int i=startIndex;i<=n;i++){
path.add(i);
backTracking(n,k,i+1);
path.removeLast(); //回溯
}
}
}
参考:代码随想录