• 【leetcode】Combination Sum (middle)


    Given a set of candidate numbers (C) and a target number (T), find all unique combinations in C where the candidate numbers sums to T.

    The same repeated number may be chosen from C unlimited number of times.

    Note:

    • All numbers (including target) will be positive integers.
    • Elements in a combination (a1, a2, … , ak) must be in non-descending order. (ie, a1 ≤ a2 ≤ … ≤ ak).
    • The solution set must not contain duplicate combinations.

    For example, given candidate set 2,3,6,7 and target 7
    A solution set is: 
    [7] 
    [2, 2, 3] 

    思路: 有规律的查找,避免重复。用递归得到所有的解

    class Solution {
    public:
        vector<vector<int> > combinationSum(vector<int> &candidates, int target) {
            vector<vector<int>> ans;
            if(candidates.empty())
                return ans;
    
            sort(candidates.begin(), candidates.end()); //从小到大排序
            recursion(ans, candidates, 0 , target);
            return ans;
        }
    
        void recursion( vector<vector<int> > &ans, vector<int> candidates, int k, int target)
        {
            static vector<int> partans;
            if(target == 0) //如果partans中数字的总和已经达到目标, 压入答案
            {
                ans.push_back(partans); 
                return;
            }
            if(target < 0)
                return;
    
            for(int i = k; i < candidates.size(); i++) //当前压入大于等于candidates[k]的数字
            {
                int sum = candidates[i];
                while(sum <= target) //数字可以压入多次,只要和小于等于目标即可
                {
                    partans.push_back(candidates[i]);
                    recursion(ans, candidates, i + 1, target - sum); //后面只压入大于当前数字的数,避免重复
                    sum += candidates[i];
                }
                while(!partans.empty() && partans.back() == candidates[i]) //状态还原
                    partans.pop_back();
            }
        }
    };

    其他人更短的递归,用参数来传partans. 省略了状态还原的代码,数字压入多次也采用了递归而不是循环

    class Solution {
    public:
    
        void search(vector<int>& num, int next, vector<int>& pSol, int target, vector<vector<int> >& result)
        {
            if(target == 0)
            {
                result.push_back(pSol);
                return;
            }
            if(next == num.size() || target - num[next] < 0)
                return;
    
            pSol.push_back(num[next]);
            search(num, next, pSol, target - num[next], result);
            pSol.pop_back();
    
            search(num, next + 1, pSol, target, result);
        }
    
        vector<vector<int> > combinationSum(vector<int> &num, int target) 
        {
            vector<vector<int> > result;
            sort(num.begin(), num.end());
            vector<int> pSol;
            search(num, 0, pSol, target, result);
            return result;    
        }
    };

    其他人动态规划的代码,还没看,速度并不快, 但很短

    class Solution {
    public:
        vector<vector<int> > combinationSum(vector<int> &candidates, int target) {
        sort(candidates.begin(), candidates.end());
        vector< vector< vector<int> > > combinations(target + 1, vector<vector<int>>());
        combinations[0].push_back(vector<int>());
        for (auto& score : candidates)
            for (int j = score; j <= target; j++){
                auto sls = combinations[j - score];
                if (sls.size() > 0) {
                    for (auto& s : sls)
                        s.push_back(score);
                    combinations[j].insert(combinations[j].end(), sls.begin(), sls.end());
                }
            }
        return combinations[target];
    }
    };
  • 相关阅读:
    jquery对同级的td做radio限制
    "javascript:void(0)"用法
    SQL 插入查询的最大ID 号 进行批量
    Java数字、货币值和百分数等的格式化处理
    PHP 注意问题
    Android Fragment真正意义上的onResume和onPause
    Android_CodeWiki_03
    Android_CodeWiki_02
    Android_CodeWiki_01
    Android 启动APP黑屏解决方案
  • 原文地址:https://www.cnblogs.com/dplearning/p/4238745.html
Copyright © 2020-2023  润新知