216 Combination Sum III [Leetcode]

44 篇文章 0 订阅
4 篇文章 0 订阅

题目内容:

Find all possible combinations of k numbers that add up to a number n, given that only numbers from 1 to 9 can be used and each combination should be a unique set of numbers.

Ensure that numbers within the set are sorted in ascending order.

Example 1:

Input: k = 3, n = 7

Output:

[[1,2,4]]

Example 2:

Input: k = 3, n = 9

Output:

[[1,2,6], [1,3,5], [2,3,4]]

解题思路:
保存一个目标对象数组,这里是1-9,然后使用回溯的方法求所有可能相加的结果。

代码实现如下:

class Solution {
private:
    vector<vector<int>> result;
    vector<int> nums;
public:
    vector<vector<int>> combinationSum3(int k, int n) {
        vector<int> mid_rlt;

        nums = vector<int>(9);
        for(int i = 1; i < 10; ++i)
            nums[i-1] = i;

        backtracking(mid_rlt, n, 0, k);

        return result;
    }

    void backtracking(vector<int> mid_rlt, int remain, int index, int count) {
        if(remain == 0 && count == 0) {
            result.push_back(mid_rlt);
            return;
        }

        for(int i = index; nums[i] <= remain && i < 9; ++i) {
            mid_rlt.push_back(nums[i]);
            backtracking(mid_rlt, remain - nums[i], i+1, count-1);
            mid_rlt.pop_back();
        }
    }
};

在上述基础上我们还可以进行剪枝。给定一个数字以及要求组成他的数字的个数,我们能够判断这些数字的个数能够组成的最大值和最小值。因此在回溯之前加上这样一个判断可以大大提高效率。

代码如下:

class Solution {
private:
    vector<vector<int>> result;
    vector<int> nums;
public:
    vector<vector<int>> combinationSum3(int k, int n) {
        vector<int> mid_rlt;

        nums = vector<int>(9);
        for(int i = 1; i < 10; ++i)
            nums[i-1] = i;

        backtracking(mid_rlt, n, 0, k);

        return result;
    }

    void backtracking(vector<int> mid_rlt, int remain, int index, int count) {
        if(getMin(count) > remain || getMax(count) < remain)
            return;

        if(count == 0) {
            if(remain == 0)
                result.push_back(mid_rlt);
            return;
        }

        for(int i = index; nums[i] <= remain && i < 9; ++i) {
            mid_rlt.push_back(nums[i]);
            backtracking(mid_rlt, remain - nums[i], i+1, count-1);
            mid_rlt.pop_back();
        }
    }

    int getMin(int k) {
        int minValue(0);
        for(int i = 0; i < k; ++i)
            minValue += nums[i];
        return minValue;
    }

    int getMax(int k) {
        int maxValue(0);
        for(int i = 0; i < k; ++i)
            maxValue += nums[8-i];
        return maxValue;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值