LeetCode刷题笔记(Combinations)

吃完中饭,笔者又刷了一道题,下面就和大家分享一下经验吧!

题目如下:

Given two integers n and k, return all possible combinations of k numbers out of 1 ... n.

Example:

Input: n = 4, k = 2
Output:
[
  [2,4],
  [3,4],
  [2,3],
  [1,2],
  [1,3],
  [1,4],
]

题意分析:

给定两个整数n、k,请返回由1到n之间的k个数构成的所有组合数。

方法一(递归回溯法)

与排列不同的是组合不需要考虑元素的位置关系,因此可直接对固定位置的各元素求解即用start持续前进,故可以参照“https://blog.csdn.net/Vensmallzeng/article/details/96473991”中的方法一进行求解,不过这里的递归终止条件有些变化,应该是temp.size()等于k时则保存temp结果到res中。

解题代码如下: 

class Solution{
public:
    vector<vector<int>> combine(int n, int k){
        vector<vector<int>> res;
        vector<int> temp;
        if (n==0) return res;
        Findcombine(n, k, 1,temp, res);
        return res;
    }

    void Findcombine(int n, int k, int start, vector<int>& temp, vector<vector<int>>& res){
        if (temp.size()==k) {
            res.push_back(temp);
            return;
        }
        for (int i = start; i <= n; i++) {
            temp.push_back(i);
            Findcombine(n, k, i+1,temp, res);
            temp.pop_back();
        }
    }
};

提交后的结果如下:

 

方法二(方法一优化)

对方法一中的递归处进行剪枝操作,因为每当循环到k-temp.size()时,已经是最后一种组合情况了,再往后循环都是数目不合法的组合,所以可以对for循环中的条件进行稍加修改以实现递归剪枝。

解题代码如下: 

class Solution{
public:
    vector<vector<int>> combine(int n, int k){
        vector<vector<int>> res;
        vector<int> temp;
        if (n==0) return res;
        Findcombine(n, k, 1,temp, res);
        return res;
    }

    void Findcombine(int n, int k, int start, vector<int>& temp, vector<vector<int>>& res){
        if (temp.size()==k) {
            res.push_back(temp);
            return;
        }
        for (int i = start; i <= n-(k-temp.size())+1; i++) {
            temp.push_back(i);
            Findcombine(n, k, i+1,temp, res);
            temp.pop_back();
        }
    }
};

提交后的结果如下:

 

方法三(迭代法)

新建一个k维数组,每次先递增最右边的数字,并将满足条件的组合存入res中,当右边的数字超过了n,则将其左边的数字+1,然后将其左边的当前数值赋值给右边,再逐一递增,直到最左边的数字也超过了n,停止循环,返回res值即可。

解题代码如下: 

class Solution {
public:
    vector<vector<int>> combine(int n, int k) {
        vector<vector<int>> res;
        vector<int> temp(k, 0);
        int i = 0;
        while (i >= 0) {
            ++temp[i];
            if (temp[i] > n) --i;
            else if (i == k - 1) res.push_back(temp);
            else {
                ++i;
                temp[i] = temp[i - 1];
            }
        }
        return res;
    }
};

提交后的结果如下:

 

 

 

日积月累,与君共进,增增小结,未完待续。 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值