【leetcode】77 组合(回溯)

题目链接:https://leetcode-cn.com/problems/combinations/

题目描述

思路

1 回溯

回溯法 是一种通过遍历所有可能成员来寻找全部可行解的算法。若候选 不是 可行解 (或者至少不是 最后一个 解),回溯法会在前一步进行一些修改以舍弃该候选,换而言之, 回溯 并再次尝试。
【leetcode】77 组合(回溯)_第1张图片
这是一个回溯法函数,它将第一个添加到组合中的数和现有的组合作为参数。 combineCore(start, curr)

  • 若组合完成- 添加到输出中。
  • 遍历从 start 到 n的所有整数。
  • ( a ) 将整数 i 添加到现有组合 curr中。
  • ( b ) 继续向组合中添加更多整数 : combineCore(start + 1, curr).
  • ( c ) 将 i 从 curr中移除,实现回溯。

复杂度分析

  • 时间复杂度: O ( k C N k ) O\left(k C_{N}^{k}\right) O(kCNk) ,其中 C N k = N ! ( N − k ) ! k ! C_{N}^{k}=\frac{N !}{(N-k) ! k !} CNk=(Nk)!k!N!是要构成的组合数。push_back/pop_back操作是常数时间。唯一耗费时间的是将长度为 k 的组合添加到输出中。
  • 空间复杂度: O ( C N k ) O\left(C_{N}^{k}\right) O(CNk),用于保存全部组合数以输出。

代码

class Solution {
public:
    vector<vector<int>> combine(int n, int k) {
        vector<vector<int>> ret;
        if(n<1 || k<1) return ret;
        vector<int> curr;
        combineCore(1, n, k,curr,ret);
        return ret;
    }
    // 回溯
    void combineCore(int start, int n, int k, vector<int> &curr, vector<vector<int>> &ret){
        if(curr.size() == k)        // 当前长度达到k
            ret.push_back(curr);
        for (int i = start; i < n+1; ++i) {
            curr.push_back(i);  // 选取i位置元素
            combineCore(i+1, n,k, curr, ret);
            curr.pop_back();    // 恢复
        }
    }
};

【leetcode】77 组合(回溯)_第2张图片

你可能感兴趣的:(LeetCode)