今天对Leetcode中Combination Sum系列的四个算法进行总结和分析,这四道题的序号分别是39,40,216,377。
39,40,216主要是用到的思想是递归,回溯。我的理解就是在Combination Sum基础上,加上了些限制条件,构成了二,三题。第三题可以看成第二题的特化版本。
DP: when solve the problem return the count
DFS : for return all the possible result
Combination Sum
Given a set of candidate numbers (C) (without duplicates) 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.
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:
std::vector<std::vector<int> > combinationSum(std::vector<int> &candidates, int target) {
std::sort(candidates.begin(), candidates.end());
std::vector<std::vector<int> > res;
std::vector<int> combination;
combinationSum(candidates, target, res, combination, 0);
return res;
}
private:
void combinationSum(std::vector<int> &candidates, int target, std::vector<std::vector<int> > &res, std::vector<int> &combination, int begin) {
if (!target)
{
res.push_back(combination);
return ;
}
for(int i=begin; i!=candidates.size() && target>= candidates[i]; i++)
{
combination.push_back(candidates[i]);
combinationSum(candidates, target - candidates[i], res, combination, i);
combination.pop_back();
}
}
};
Combination Sum II
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.
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]
]
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 也可以在最后判断res结果中是否含有重复结果 但是在这里判断相对优化了些
local.push_back(num[i]);
findCombination(res,i+1,target-num[i],local,num); // recursive componenet
local.pop_back();
}
}
}
};
Combination Sum III
Find all possible combinations of k numbers that add up to a number n, given that only numbers from 1 to 9 can be used and each combination should be a unique set of numbers.
Example 1:
Input: k = 3, n = 7
Output:
[[1,2,4]]
Example 2:
Input: k = 3, n = 9
Output:
[[1,2,6], [1,3,5], [2,3,4]]
class Solution {
public:
vector<vector<int>> combinationSum3(int k, int n) {
std::vector<int> candidates;
for(int i=1; i<=9; i++)
{
candidates.push_back(i);
}
std::vector<std::vector<int> > res;
std::vector<int> combination;
int target = n;
combinationSum(candidates, target, res, combination, 0, k);
return res;
}
private:
void combinationSum(std::vector<int> &candidates, int target, std::vector<std::vector<int> > &res, std::vector<int> &combination, int begin, int count) {
if (!target&&!count)
{
res.push_back(combination);
return ;
}
for(int i=begin; i!=candidates.size() && target>= candidates[i]; i++)
{
combination.push_back(candidates[i]);
combinationSum(candidates, target - candidates[i], res, combination, i+1,count-1);
combination.pop_back();
}
}
};
Combination Sum IV
Given an integer array with all positive numbers and no duplicates, find the number of possible combinations that add up to a positive integer target.
Example:
nums = [1, 2, 3]
target = 4
The possible combination ways are:
(1, 1, 1, 1)
(1, 1, 2)
(1, 2, 1)
(1, 3)
(2, 1, 1)
(2, 2)
(3, 1)
Note that different sequences are counted as different combinations.
Therefore the output is 7.
class Solution {
public:
int combinationSum4(vector<int>& nums, int target) {
vector<int> dp(target + 1);
dp[0] = 1;
sort(nums.begin(), nums.end());
for (int i = 1; i <= target; ++i) {
for (auto a : nums) {
if (i < a) break;
dp[i] += dp[i - a];
}
}
return dp.back();
}
};
[参考](http://www.cnblogs.com/grandyang/p/5705750.html)
[参考](http://blog.csdn.net/ljiabin/article/details/41957533)
[参考](https://leetcode.com/problems/combination-sum-iv/#/solutions)