题目描述
给定两个整数 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
题目解析
- 组合问题,从数字
1
到数字n
每一个数字都可以作为根 - 很显然数字还不能重复使用
code 1
class Solution {
private List<List<Integer>> ans;
// 标记被使用过的数字
private boolean[] used;
private int n;
private int k;
public List<List<Integer>> combine(int n, int k) {
// 初始化结果集 和 标记集
ans = new ArrayList<>();
used = new boolean[n + 1];
// 初始化全局变量
this.n = n;
this.k = k;
List<Integer> local = new ArrayList<>();
// 1 :表示从 1 开始选择
// local :保存选择路径上的元素
dfs(local, 1);
return ans;
}
private void dfs(List<Integer> local, int idx) {
// 如果剩下的数全部都选择不够 k 个数了直接返回
if(local.size() + (n - idx + 1) < k) {
return;
}
// 足够 k 个数了
if(local.size() == k) {
// 加入到结果集合中
ans.add(new ArrayList<>(local));
return;
}
// 相当于遍历有序数组.
for(int i = idx;i <= n;i++) {
if(used[i]){
continue;
}
// 选择当前元素
local.add(i);
// 标记
used[i] = true;
// 深度搜索
dfs(local, i + 1);
// 取消标记
used[i] = false;
// 撤销选择
local.remove(local.size() - 1);
}
}
}
code 2
class Solution {
private List<List<Integer>> ans;
private int n;
private int k;
public List<List<Integer>> combine(int n, int k) {
// 初始化结果集 和 标记集
ans = new ArrayList<>();
// 初始化全局变量
this.n = n;
this.k = k;
List<Integer> local = new ArrayList<>();
// 1 :表示从 1 开始选择
// local :保存选择路径上的元素
dfs(local, 1);
return ans;
}
private void dfs(List<Integer> local, int idx) {
// 如果剩下的数全部都选择不够 k 个数了直接返回
if(local.size() + (n - idx + 1) < k) {
return;
}
// 足够 k 个数了
if(local.size() == k) {
// 加入到结果集合中
ans.add(new ArrayList<>(local));
return;
}
// 对于每一个元素面临 2 种情况,选 or 不选
// 不选择当前元素
dfs(local, idx + 1);
// 选择当前元素
local.add(idx);
dfs(local, idx + 1);
local.remove(local.size() - 1);
}
}
标签:leet,code,idx,int,List,private,77,ans,local
From: https://blog.51cto.com/u_16079703/8429958