77. 组合【 力扣(LeetCode) 】

文章目录

零、原题链接

77. 组合

一、题目描述

给定两个整数 nk,返回范围 [1, n] 中所有可能的 k 个数的组合。

你可以按 任何顺序 返回答案。

二、测试用例

示例 1:

cpp 复制代码
输入:n = 4, k = 2
输出:
[
  [2,4],
  [3,4],
  [2,3],
  [1,2],
  [1,3],
  [1,4],
]

示例 2:

cpp 复制代码
输入:n = 1, k = 1
输出:[[1]]

提示:

cpp 复制代码
1 <= n <= 20
1 <= k <= n

三、解题思路

  1. 基本思路:
      回溯法 + 剪枝。
      为了保证不重复,我们只需要保证每个序列都是递增,所以序列的每个位置取值都有范围,第 i 个数的取值范围为 [i,n-k+i]
  2. 具体思路:
    • 回溯:
      • 如果该元素超出该位置的范围,则返回。【剪枝】
      • 序列 vec 添加该元素。
      • 如果是最后一个元素,则将序列 vec 添加到 ans 并弹出最后一个元素。
      • 递归遍历下一个位置的元素。
      • 弹出最后一个元素【回溯要恢复状态】

四、参考代码

时间复杂度: O ( k ⋅ C n k ) \Omicron(k\cdot C_n^k) O(k⋅Cnk) 【一共 C n k C_n^k Cnk 的序列,每个序列 k 个元素】

空间复杂度: O ( k ) \Omicron(k) O(k) 【递归栈最深为 k 】

cpp 复制代码
class Solution {
public:
    vector<vector<int>> ans;
    vector<int> vec;
    int _n;

    void dfs(const int& i, const int& k) {
        if (i > _n - k + 1)
            return;

        vec.emplace_back(i);
        if (k == 1) {
            ans.emplace_back(vec);
            vec.pop_back();
            return;
        }

        for (int j = i + 1; j <= _n; j++) {
            dfs(j, k - 1);
        }

        vec.pop_back();
    }

    vector<vector<int>> combine(int n, int k) {
        _n = n;
        int t = n - k + 1;
        
        for (int i = 1; i <= t; i++)
            dfs(i, k);

        return ans;
    }
};
相关推荐
小刘的AI小站7 分钟前
leetcode hot100 二叉搜索树
算法·leetcode
自信的小螺丝钉8 分钟前
Leetcode 876. 链表的中间结点 快慢指针
算法·leetcode·链表·指针
红豆怪怪9 分钟前
[LeetCode 热题 100] 32. 最长有效括号
数据结构·python·算法·leetcode·动态规划·代理模式
参.商.10 分钟前
【Day21】146.LRU缓存 (Least Recently Used)
leetcode·缓存·golang
愚润求学15 分钟前
【贪心算法】day6
c++·算法·leetcode·贪心算法
AI 嗯啦26 分钟前
计算机的排序方法
数据结构·算法·排序算法
沐怡旸34 分钟前
【底层机制】右值引用是什么?为什么要引入右值引用?
c++·面试
l12345sy39 分钟前
Day23_【机器学习—聚类算法—K-Means聚类 及评估指标SSE、SC、CH】
算法·机器学习·kmeans·聚类·sse·sc·ch
_Coin_-1 小时前
算法训练营DAY58 第十一章:图论part08
数据结构·算法·图论
scx201310041 小时前
P13929 [蓝桥杯 2022 省 Java B] 山 题解
c++·算法·蓝桥杯·洛谷