• Combination Sum


    题目链接:

    回溯算法的剪枝非常重要!!

    这个题是一个NP问题,方法仍然是N-Queens中介绍的套路。基本思路是先排好序,然后每次递归中把剩下的元素一一加到结果集合中,并且把目标减去加入的元素,然后把剩下元素(包括当前加入的元素)放到下一层递归中解决子问题。算法复杂度因为是NP问题,所以自然是指数量级的。

    简单的回溯法(递归实现).

    比如对于数组3,2,6,7,target = 7,对数组排序得到[2,3,6,7]

    1、第1个数字选取2, 那么接下来就是解决从数组[2,3,6,7]选择数字且target = 7-2 = 5

    2、第2个数字选择2,那么接下来就是解决从数组[2,3,6,7]选择数字且target = 5-2 = 3

    3、第3个数字选择2,那么接下来就是解决从数组[2,3,6,7]选择数字且target = 3-2 = 1

    4、此时target = 1小于数组中的所有数字,失败,回溯,重新选择第3个数字

    5、第3个数字选择3,那么接下来就是解决从数组[2,3,6,7]选择数字且target = 3-3 = 0

    6、target = 0,找到了一组解,继续回溯寻找其他解。

    贴上代码:

    #include <iostream>     // std::cout
    #include <algorithm>    // std::is_heap_until, std::sort, std::reverse
    #include <vector>       // std::vector
    using namespace std;
    
    class Solution {
    public:
        vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
    
            vector<int> temp;
            sort(candidates.begin(), candidates.end());
            if (candidates.size() == 0)//还有candidates==NULL的情况
                return res;
            helper(candidates, 0, target, res, temp);//
            return res;
        }
        void show(){
            for (int i = 0; i < res.size(); i++)
            {
                for (int j = 0; j < res[i].size(); j++)
                    cout << res[i][j] << " ";
                cout << endl;
            }
        }
    private:
        void helper(vector<int>& candidates, int index, int target,vector<vector<int>>& res,vector<int>& temp){
            if (target < 0)
                return;
            if (0 == target){
                res.push_back(temp);
                return;
            }
            for (int i = index; i < candidates.size(); i++){  //这儿i=index,千万别再写成了i=0
                if (i>0 && candidates[i] == candidates[i - 1])
                    continue;
                //if (candidates[i] <= target){//这儿不需要这一句,让其添加就好了,否则target就不会有变为负数的机会了
                    temp.push_back(candidates[i]);
                    target -= candidates[i];
                    //helper(candidates, i, target, res, temp);//问题:这个target的值并没有随着递归返回而恢复原来的值
                    helper(candidates, i, target, res, temp);
                    target += candidates[i];  //这个地方也非常关键
                    temp.pop_back();
                //}
            }
        }
    private:
        vector<vector<int>> res;
    };
    
    
    int main() {
        vector<int> arr{1 };
        Solution test;
        test.combinationSum(arr, 1);
        test.show();
    
        return 0;
    }
    手里拿着一把锤子,看什么都像钉子,编程界的锤子应该就是算法了吧!
  • 相关阅读:
    PHPMailer发送邮件失败:SMTP connect failed
    QQ邮箱开启SMTP服务的步骤
    php中PHPMailer发送带附件的电子邮件方法
    怎么获取smtp服务器用户帐号和密码
    How To Install Flash Player In Ubuntu 10.04 Lucid Lynx,install firefox flash plugin addon for ubuntu
    Rails 3.1 execjs and Could not find a JavaScript runtime
    railser
    Harmony: JavaScript And A DOM Environment In Ruby
    郭德纲继10月1日发微博感叹“暗箭起同行”,疑似暗讽姜昆“江郎才尽”后
    算命先生也用电脑了
  • 原文地址:https://www.cnblogs.com/chess/p/5255762.html
Copyright © 2020-2023  润新知