LeetCode 39/40. Combination Sum i, ii
Posted 枯萎的海风
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode 39/40. Combination Sum i, ii相关的知识,希望对你有一定的参考价值。
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的主要内容,如果未能解决你的问题,请参考以下文章