首页 简历|笔试面试

77.组合

  • 25年9月4日 发布
  • 26.98KB 共3页
77.组合77.组合77.组合

77. 组合

题意

给定两个整数 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]]

分析

本题是一道经典的搜索入门题。

我们一开始可能会想到,利用 k 层的枚举,每层都从 1 到 n 枚举一遍。这样子就产生了

[1,1,1,1,1]、[1,1,1,1,2]…… 诸如此类的所有含有重复数字的集合,但是这样子,我们就

要对含有重复数字的集合进行去重。

如果依靠上述的算法,我们不仅需要花$ O(n^k) $来枚举,还要在去重上大费周章,太麻

烦了,时间复杂度也难以接受。

所以我们考虑换个方法,从排列的本质来考虑,其实我们只需要从 n 个数字中挑出 k 个即

可,所以我们可以利用深度优先搜索来模拟这个选择的过程,代码如下:

void DFS(List<Integer> list,int pos,int limit,int maxInt) {

if(pos > maxInt)

return ;

if(list.size() == limit){

res.add(new ArrayList<>(list));

return ;

}

list.add(pos);

DFS(list,pos + 1,limit,maxInt);

list.remove(list.size() - 1);

DFS(list,pos + 1,limit,maxInt);

}

我们来分析一下这个方法,list 是已经选择的数字集合,limit 是最多能选的数字,

maxInt 则是最大能选择的数字。

1. 判断当前选择的数字有没有超过 maxInt,如果超过,说明已经枚举完所有的数字

了,直接返回。

2. 判断当前已经选择数字的数量是否已经和 k 相等,如果相等,说明已经找到了合法的

答案,直接返回。

3. 接下来就是选择当前数字和不选择当前数字,继续下一次搜索。

这样子的时间复杂度就是$ O(k*) ,因 为 我 们 一 共 找 出 了

个 可 行 的 集 合 , 然 后 又 用 O(k) $的时间将其计入答案。

我们还可以对它进行剪枝优化(剪枝:在保证搜索的正确性、准确性的前提下,省略一些

不必要的循环和枚举)。

对于本题来说,if(pos > maxInt)也能够算作剪枝的一种,但它是必要的剪枝,因为如果

没用它,我们的算法就不没法停止。它是剪枝,也是搜索算法的结束条件。

除此之外,我们还可以对它进行优化,如果当前 list 的元素数量加上还没有被选择过的数

字总量小于 k,那么就算是全都选上了,也不能满足题目的条件——选够 k 个元素,这一

大块的无必要的枚举就可以直接剪掉。

最终代码:

class Solution {

List<List<Integer>> res = new ArrayList<>();

public List<List<Integer>> combine(int n, int k) {

List<Integer> list = new ArrayList<>();

DFS(list,1,k,n);

return res;

}

private void DFS(List<Integer> list,int pos,int limit,int maxInt) {

if(list.size() + (maxInt - pos + 1) < limit)

return ;

if(list.size() == limit){

res.add(new ArrayList<>(list));

return ;

}

list.add(pos);

DFS(list,pos + 1,limit,maxInt);

list.remove(list.size() - 1);

DFS(list,pos + 1,limit,maxInt);

}

}

效率不错:

总结

搜索算法是一类常用的暴力算法,但是如何优雅地暴力是我们刷题党需要考虑的,一边优

化程序,一边优化自身的水平。

力扣链接:https://leetcode.cn/problems/combinations/

开通会员 本次下载免费

所有资料全部免费下载! 推荐用户付费下载获取返佣积分! 积分可以兑换商品!
一键复制 下载文档 联系客服