「这是我参与11月更文挑战的第7天,活动详情查看:2021最后一次更文挑战」
前言
力扣第七十七题 组合 如下所示:
给定两个整数 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],所以从1开始 - 如果当前层结果的大小为
k则将当前结果加入结果集
举个例子
此处以示例中的 n = 4, k = 2 作为例子
- 先选择
1可以得到的结果有[1, 2],[1, 3]和[1, 4] - 再选择
2可以得到的结果有[2, 3],[2, 4] - 再选择
3可以得到[3, 4] - 最终将得到的结果集返回即可
值得注意的有如下两点:
- 每次当前层递归结束后,应将当前层添加的元素删除
- 应适当的剪枝:当临时一组结果的长度和还剩余的元素个数加起来都没有
k大的话,应该终止当前层的递归。(例如:当n = 4, k = 3时,在递归的过程中,某一组的第一个元素选择3时,就应立即停止向下递归了。因为后面只有一个元素了,即使都选择了都无法构成正确的结果。)
二、实现
实现代码
实现代码与思路中保持一致,使用的时 List<Integer> 来存储某一组的结果
List<Integer> temp = new ArrayList<>();
List<List<Integer>> ans = new ArrayList<>();
public List<List<Integer>> combine(int n, int k) {
dfs(1, n, k);
return ans;
}
public void dfs(int cur, int n, int k) {
// 剪枝
if (temp.size() + (n - cur + 1) < k) {
return;
}
// 记录结果
if (temp.size() == k) {
ans.add(new ArrayList<>(temp));
return;
}
temp.add(cur);
dfs(cur + 1, n, k);
temp.remove(temp.size() - 1);
dfs(cur + 1, n, k);
}
测试代码
public static void main(String[] args) {
new Number77().combine(4, 3);
}
结果
三、总结
我后面又看到力扣上面还可以使用 字典序法 来解决此问题,这个方法还是比较难理解的,有兴趣的可以自行去力扣官方题解看一下!
感谢看到最后,非常荣幸能够帮助到你~♥
如果你觉得我写的还不错的话,不妨给我点个赞吧!如有疑问,也可评论区见~