目录
39. Combination Sum
Medium
302294Add to ListShare
Given a set of candidate numbers (candidates
) (without duplicates) and a target number (target
), find all unique combinations in candidates
where the candidate numbers sums to target
.
The same repeated number may be chosen from candidates
unlimited number of times.
Note:
- All numbers (including
target
) will be positive integers. - The solution set must not contain duplicate combinations.
Example 1:
Input: candidates = [2,3,6,7], target = 7, A solution set is:[ [7], [2,2,3] ]
Example 2:
Input: candidates = [2,3,5], target = 8, A solution set is:[ [2,2,2,2], [2,3,3], [3,5] ]
#include"pch.h"
#include<iostream>
#include<stack>
#include<string>
#include<vector>
#include<algorithm>
using namespace std;
/*39. Combination Sum
1.典型DFS
Runtime: 20 ms, faster than 41.01% of C++ online submissions for Combination Sum.
Memory Usage: 12.7 MB, less than 40.28% of C++ online submissions for Combination Sum.*/
void DFS(vector<int> candidates, int target, int start, vector<int> &out, vector<vector<int> > &res) {
if (target == 0) {
res.push_back(out);
return;
}
for (int i = start; i < candidates.size(); i++) {
if (target - candidates[i] >= 0) {
out.push_back(candidates[i]);
DFS(candidates, target - candidates[i], i, out, res);
out.pop_back();
}
}
return;
}
vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
vector<vector<int> > res;
vector<int> out;
DFS(candidates, target, 0, out, res);
return res;
}
/*2.给数组排序,遇到大于target的就不再递归了
Runtime: 24 ms, faster than 34.62% of C++ online submissions for Combination Sum.
Memory Usage: 12.9 MB, less than 40.28% of C++ online submissions for Combination Sum.*/
vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {
sort(candidates.begin(), candidates.end());
vector<vector<int> > res;
for (int i = 0; i < candidates.size(); i++) {
if (candidates[i] > target) break;
else if(candidates[i]==target){
res.push_back({ candidates[i] }); break;
}
else {
vector<int> vec = vector<int>(candidates.begin() + i, candidates.end());
vector<vector<int> > tmp = combinationSum2(vec, target - candidates[i]);
for (auto a : tmp) {
a.insert(a.begin(), candidates[i]);
res.push_back(a);
}
}
}
return res;
}
/*3.迭代,建立三维数组,dp[i]表示目标数为i+1的解法的集合,i从1到target,
对于每个i,建立一个二维数组cur,遍历原数组,如果遍历到的数字大于i,break;
如果遍历到的数字=i,那么当前数字形成一个数组加入cur;
如果遍历到的数组<i,那么遍历dp[i-candidates[j]-1]中的所有数组,
如果当前数字大于数组首元素,则break,否则就将当前数字加入数组开头,再将数组加入cur
Runtime: 36 ms, faster than 26.08% of C++ online submissions for Combination Sum.
Memory Usage: 18.3 MB, less than 20.83% of C++ online submissions for Combination Sum.*/
vector<vector<int>> combinationSum3(vector<int>& candidates, int target) {
vector<vector<vector<int> > > dp;
sort(candidates.begin(), candidates.end());
for (int i = 1; i <= target; i++) {
vector<vector<int> > cur;
for (int j = 0; j < candidates.size(); j++) {
if (candidates[j] > target) break;
else if (candidates[j] == i) {
cur.push_back({ candidates[j] });
break;
}
else {
for (auto a : dp[i - candidates[j] - 1]) {
if (candidates[j] > a.front()) continue;
a.insert(a.begin(), candidates[j]);
cur.push_back(a);
}
}
}
dp.push_back(cur);
}
return dp[target - 1];
}
int main() {
vector<int> num = {2,3,6,7};
vector<vector<int> > res = combinationSum2(num, 7);
for (int i = 0; i < res.size(); i++) {
for (int j = 0; j < res[i].size(); j++) {
cout << res[i][j] << " ";
}
cout << endl;
}
return 0;
}
40. Combination Sum II
Medium
133855Add to ListShare
Given a collection of candidate numbers (candidates
) and a target number (target
), find all unique combinations in candidates
where the candidate numbers sums to target
.
Each number in candidates
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.
Example 1:
Input: candidates = [10,1,2,7,6,1,5], target = 8, A solution set is: [ [1, 7], [1, 2, 5], [2, 6], [1, 1, 6] ]
Example 2:
Input: candidates = [2,5,2,1,2], target = 5, A solution set is: [ [1,2,2], [5] ]
#include"pch.h"
#include<iostream>
#include<stack>
#include<string>
#include<vector>
#include<algorithm>
using namespace std;
/*40. Combination Sum II
DFS:
Runtime: 8 ms, faster than 85.54% of C++ online submissions for Combination Sum II.
Memory Usage: 11.6 MB, less than 13.16% of C++ online submissions for Combination Sum II.*/
void DFS(vector<int> candidates, vector<int> &out, vector<vector<int> > &res,int target,int start) {
if (target == 0) {
res.push_back(out);
return;
}
for (int i = start; i < candidates.size(); i++) {
if (target - candidates[i] >= 0 ) {
if (i > start && candidates[i] == candidates[i - 1]) continue;
out.push_back(candidates[i]);
DFS(candidates, out, res, target - candidates[i], i+1);
out.pop_back();
}
else break;
}
return;
}
vector<vector<int>> combinationSum1(vector<int>& candidates, int target) {
vector<int> vis(candidates.size());
vector<vector<int> > res;
vector<int> out;
sort(candidates.begin(), candidates.end());
DFS(candidates, out, res, target, 0);
return res;
}
int main() {
vector<int> num = { 10,1,2,7,6,1,5 };
vector<vector<int> > res = combinationSum1(num, 8);
for (int i = 0; i < res.size(); i++) {
for (int j = 0; j < res[i].size(); j++) {
cout << res[i][j] << " ";
}
cout << endl;
}
return 0;
}
216. Combination Sum III
Medium
84646Add to ListShare
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.
Note:
- All numbers will be positive integers.
- The solution set must not contain duplicate combinations.
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]]
#include"pch.h"
#include<iostream>
#include<stack>
#include<string>
#include<vector>
#include<algorithm>
using namespace std;
/*216. Combination Sum III
Runtime: 4 ms, faster than 63.71% of C++ online submissions for Combination Sum III.
Memory Usage: 8.6 MB, less than 100.00% of C++ online submissions for Combination Sum III.*/
void DFS(vector<int> &out, vector<vector<int> > &res, int target, int k,int start) {
if (target == 0 && k == 0) {
res.push_back(out);
return;
}
else if (target > 0 && k > 0) {
for (int i = start; i <=9; i++) {
if (target - i >= 0) {
out.push_back(i);
DFS(out, res, target - i, k - 1, i + 1);
out.pop_back();
}
else return;
}
}
return;
}
vector<vector<int>> combinationSum3(int k, int n) {
vector<vector<int> > res;
vector<int> out;
DFS(out, res, n, k, 1);
return res;
}
int main() {
vector<vector<int> > res=combinationSum3(3, 9);
for (int i = 0; i < res.size(); i++) {
for (int j = 0; j < res[i].size(); j++) {
cout << res[i][j] << " ";
}
cout << endl;
}
return 0;
}
377. Combination Sum IV
Medium
1128135Add to ListShare
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.
Follow up:
What if negative numbers are allowed in the given array?
How does it change the problem?
What limitation we need to add to the question to allow negative numbers?
Credits:
Special thanks to @pbrother for adding this problem and creating all test cases.
#include"pch.h"
#include<iostream>
#include<stack>
#include<string>
#include<vector>
#include<algorithm>
#include<unordered_map>
using namespace std;
/*377. Combination Sum IV
1.DFS:超时*/
void DFS(int &res,int target,vector<int> nums) {
if (target == 0) {
res++;
return;
}
for (int i = 0; i < nums.size(); i++) {
if (target - nums[i] >= 0) {
DFS( res, target - nums[i], nums);
}
else return;
}
return;
}
int combinationSum1(vector<int>& nums, int target) {
sort(nums.begin(), nums.end());
int res = 0;
DFS( res, target, nums);
return res;
}
/*2.与爬楼梯问题相似,假设nums:{x,y,z}
dp[i]=dp[i-x]+dp[i-y]+dp[i-z]
但是[3,33,333],10000,超过long long,无法通过*/
int combinationSum2(vector<int>& nums, int target) {
sort(nums.begin(), nums.end());
vector<long long> dp(target+1);
dp[0] = 1;
for (int i = 1; i <=target; i++) {
for (int j = 0; j < nums.size(); j++) {
if (nums[j] <= i) dp[i] += dp[i - nums[j]];
else break;
}
}
return dp.back();
}
/*3.递归+记忆数组
Runtime: 4 ms, faster than 67.79% of C++ online submissions for Combination Sum IV.
Memory Usage: 10.1 MB, less than 30.00% of C++ online submissions for Combination Sum IV.*/
int digui(vector<int> &nums, int target, unordered_map<int, int> &demo) {
if (target < 0) return 0;
if (target == 0) return 1;
if (demo.count(target)) return demo[target];
int res = 0;
for (int i = 0; i < nums.size(); i++) {
res += digui(nums, target - nums[i], demo);
}
demo[target] = res;
return res;
}
int combinationSum3(vector<int>& nums, int target) {
unordered_map<int, int> mp;
return digui(nums, target, mp);
}
int main() {
vector<int> nums = {3,33,333 };
cout << combinationSum3(nums,10000);
return 0;
}