216 Combination Sum III [Leetcode]

題目內容:

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;
    }
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章