LeetCode-216. Combination Sum III

Description

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.

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]]

Solution 1

class Solution {
public:
    void findcom(vector<vector<int>> &res, vector<int> cur, int helper[], int k, int n){
        if(k==1){
            if(n>0 && n<10 && helper[n-1]>0){
                cur.push_back(n);
                res.push_back(cur);
                return;
            }
        } else {
            for(int i=0; i<9; i++){
                if(helper[i]>0 && helper[i]<n){
                    cur.push_back(helper[i]);
                    helper[i]=-helper[i];
                    findcom(res, cur, helper, k-1, n-1-i);
                    cur.pop_back();
                }
            }
        }
    }
    vector<vector<int>> combinationSum3(int k, int n) {
        int helper[9]={1,2,3,4,5,6,7,8,9};
        vector<vector<int>> res;
        vector<int> cur;
        findcom(res, cur, helper, k, n);
        return res;
    }
};

Solution 2(C++)

class Solution {
public:
    void findcom(vector<vector<int>> &res, vector<int> cur, vector<int> helper, int k, int n){
        if(k==1){
            if(n>0 && n<10 && helper[n-1]>0){
                cur.push_back(n);
                res.push_back(cur);
                return;
            }
        } else {
            for(int i=0; i<9; i++){
                if(helper[i]>0 && helper[i]<n){
                    cur.push_back(helper[i]);
                    helper[i]=-helper[i];
                    findcom(res, cur, helper, k-1, n-1-i);
                    cur.pop_back();
                }
            }
        }
    }
    vector<vector<int>> combinationSum3(int k, int n) {
        vector<int> helper={1,2,3,4,5,6,7,8,9};
        vector<vector<int>> res;
        vector<int> cur;
        findcom(res, cur, helper, k, n);
        return res;
    }
};

Solution 3(C++)

class Solution {
public:
    vector<vector<int>> combinationSum3(int k, int n) {
        vector<vector<int>> result;
        vector<int> temp(k, 0);
        int depth = 0;
        int sum = 0;
        while (depth >= 0) {
            if (depth == k) {
                if (sum == n) {
                    result.push_back(temp);
                }
                depth--;
                continue;
            }

            if (depth > 0 && temp[depth] == 0) {
                temp[depth] = temp[depth - 1] + 1;
                sum += temp[depth];
            } else {
                temp[depth]++;
                sum++;
            }

            if (temp[depth] == 10) {
                sum -= temp[depth];
                temp[depth] = 0;
                depth--;
                continue;
            }

            depth++;
        }

        return result;
    }
};

算法分析

以上三个解法中,解法一与解法二中,解法一是错误的,解法二是正确的。其原因非常有意思。

首先比较重要的一点就是,我算是对值传递与引用传递有了新的理解了。对于值传递,其实就是在新的子函数体中开辟一块新的空间,用来存放值传递的值。那么函数结束之后,传递的参数其实是不会发生变化的。这一点非常适合回溯算法中的特点,那就是在每递归一次,相当于往深走一层,那么下一层的参数不会回传到上一层。每一层参数的变化只在本层变化。

所以基于此,对于需要全局改变的量,比如res,应该传递引用。对于每一层不同的量,比如,cur,k,n都应该传递值。当下一层函数执行完成之后,传递值的不会改变,只在下一层改变。此外,对于helper,解法一中是通过静态数组来储存的,但解法二中是通过vector< int >,解法一失败,但解法二成功。因为解法一虽然是传递形式为:int helper[],但其实这是将helper数组的名字,也就是指针传递,所以,helper还是会被修改。所以可以使用vector< int >

程序分析

略。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值