首页 > 其他 > 详细

LeetCode 39/40. Combination Sum i, ii

时间:2016-05-07 10:50:47      阅读:228      评论:0      收藏:0      [点我收藏+]

1. 题目描述

39

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]

40

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

Each number in C may only be used once in the combination.

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 10,1,2,7,6,1,5 and target 8,
A solution set is:
[1, 7]
[1, 2, 5]
[2, 6]
[1, 1, 6]

2. 解题思路

使用回溯的算法思想, 对于含有重复元素的, 可以在最后进行排序, 去除重复元素实现需求

3. code

3.1 39

class Solution {
public:
    vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
        sort(candidates.begin(), candidates.end());
        vector<vector<int>> res;
        vector<int> tmp;
        helper(res, tmp, candidates, target, 0);
        return res;
    }

private:
    void helper(vector<vector<int>> & res, vector<int> & cur_set, const vector<int>& candidates, int target, int depth){
        if (target == 0){
            res.push_back(cur_set);
            return;
        }

        if (target < 0 || depth == candidates.size())
            return;

        helper(res, cur_set, candidates, target, depth + 1);
        cur_set.push_back(candidates[depth]);
        helper(res, cur_set, candidates, target - candidates[depth], depth);
        cur_set.pop_back();
    }
};

3.2 40

class Solution {
public:
    vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {
        sort(candidates.begin(), candidates.end());
        vector<vector<int>> res;
        vector<int> tmp;
        helper(res, tmp, candidates, target, 0);
        sort(res.begin(), res.end());
        res.erase(unique(res.begin(), res.end()), res.end());
        return res;
    }

private:
    void helper(vector<vector<int>> & res, vector<int> & cur_set, const vector<int>& candidates, int target, int depth){
        if (target == 0){
            res.push_back(cur_set);
            return;
        }

        if (target < 0 || depth >= candidates.size())
            return;

        helper(res, cur_set, candidates, target, depth + 1);
        cur_set.push_back(candidates[depth]);
        helper(res, cur_set, candidates, target - candidates[depth], depth + 1);
        cur_set.pop_back();
    }
};

4. 大神解法

这段检测重复元素的代码是核心

if(i&&num[i]==num[i-1]&&i>order) continue; // check duplicate combination
/*
At the beginning, I stuck on this problem. After careful thought, I think this kind of backtracking contains a iterative component and a resursive component so I‘d like to give more details to help beginners save time. The revursive component tries the elements after the current one and also tries duplicate elements. So we can get correct answer for cases like [1 1] 2. The iterative component checks duplicate combinations and skip it if it is. So we can get correct answer for cases like [1 1 1] 2.
*/
class Solution {
public:
    vector<vector<int> > combinationSum2(vector<int> &num, int target) 
    {
        vector<vector<int>> res;
        sort(num.begin(),num.end());
        vector<int> local;
        findCombination(res, 0, target, local, num);
        return res;
    }
    void findCombination(vector<vector<int>>& res, const int order, const int target, vector<int>& local, const vector<int>& num)
    {
        if(target==0)
        {
            res.push_back(local);
            return;
        }
        else
        {
            for(int i = order;i<num.size();i++) // iterative component
            {
                if(num[i]>target) return;
                if(i&&num[i]==num[i-1]&&i>order) continue; // check duplicate combination
                local.push_back(num[i]),
                findCombination(res,i+1,target-num[i],local,num); // recursive componenet
                local.pop_back();
            }
        }
    }
};

LeetCode 39/40. Combination Sum i, ii

原文:http://blog.csdn.net/zhyh1435589631/article/details/51330804

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!