• 【LeetCode】39. Combination Sum (2 solutions)


    Combination Sum

    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] 

    寻找target成员的过程中,如果candidates[i]是组成target的成员之一,那么寻找target-candidates[i]的子问题与原题就完全一致,因此是典型的递归。

    参数列表中:result设为全局变量,用于记录所有可行的路径,因此使用引用(&);curPath是每次递归栈中独立部分,因此使用拷贝复制

    解法一:使用map去重

    class Solution {
    public:
        vector<vector<int> > combinationSum(vector<int> &candidates, int target) {
            sort(candidates.begin(), candidates.end());
            vector<vector<int> > ret;
            map<vector<int>, bool> m;
            vector<int> cur;
            Helper(ret, cur, candidates, target, m, 0);
            return ret;
        }
        void Helper(vector<vector<int> >& ret, vector<int> cur, vector<int> &candidates, int target, map<vector<int>, bool> &m, int ind)
        {
            if(target == 0)
            {
                if(m[cur] == false)
                {
                    ret.push_back(cur);
                    m[cur] = true;
                }
            }
            else
            {
                for(int i = ind; i < candidates.size() && candidates[i] <= target; i ++)
                {// for each candidate
                    int val = candidates[i];
                    cur.push_back(val);
                    Helper(ret, cur, candidates, target-val, m, i); // duplication allowed
                    cur.pop_back();
                }
            }
        }
    };

    解法二:

    稍作分析可知,重复结果的原因在于candidates中的重复元素。

    因为我们默认每个位置的元素可以重复多次,而不同位置的元素是不同的。

    对candidates的排序及去重的目的就是防止结果的重复,比如7 --> 2,2,3/2,3,2/3,2,2

    注:去重函数unique的用法

    1、先排序,因为unique只会去掉连续元素中的重复元素

    sort(candidates.begin(), candidates.end());

    2、调用unique函数

    vector<int>::iterator iter = unique(candidates.begin(), candidates.end());

    执行完毕之后,返回的iter指向去重之后新数组的尾部,

    例如:1,2,2,4,4,5

    得到:1,2,4,5,?,?

                       ^

                      iter

    3、最后删除iter到end()之间的所有元素

    candidates.erase(iter, candidates.end());
    class Solution {
    public:
        vector<vector<int> > combinationSum(vector<int> &candidates, int target) {
            sort(candidates.begin(), candidates.end());
            vector<int>::iterator iter = unique(candidates.begin(), candidates.end());
            candidates.erase(iter, candidates.end());
            
            vector<vector<int> > ret;
            vector<int> cur;
            Helper(ret, cur, candidates, target, 0);
            return ret;
        }
        void Helper(vector<vector<int> >& ret, vector<int> cur, vector<int> &candidates, int target, int pos)
        {
            if(target == 0)
            {
                ret.push_back(cur);
            }
            else
            {
                for(int i = pos; i < candidates.size() && candidates[i] <= target; i ++)
                {
                    //candidates[i] included
                    cur.push_back(candidates[i]);
                    //next position is still i, to deal with duplicate situations
                    Helper(ret, cur, candidates, target-candidates[i], i);
                    //candidates[i] excluded
                    cur.pop_back();
                }
            }
        }
    };

  • 相关阅读:
    玩家移动
    人物上线(激活玩家之后)
    map 玩家上线
    无锁的环形队列
    随笔
    std::bind
    如何查找文件中的schema约束
    myeclipse便捷导包方式
    21 求1+2!+3!+...+20!的和
    20 求出这个数列的前 20 项之和
  • 原文地址:https://www.cnblogs.com/ganganloveu/p/3961332.html
Copyright © 2020-2023  润新知