Leetcode 39
https://leetcode.com/problems/combination-sum/
题意:给定一个正
整数数组,从数组中找组合,使得组合出来的数的和为t。可以重复选
题解:dfs,有一个u记录我当前从u位数字开始选,每一层dfs我都从第u位往后面选择数字放进tmp数组中
class Solution {
public:
vector<vector<int>> res;
vector<vector<int>> combinationSum(vector<int>& a, int t) {
vector<int> tmp;
dfs(a, t, 0, 0, tmp);
return res;
}
void dfs(vector<int>& a, int t, int u, int sum, vector<int>& tmp) {
if(sum == t) {
res.push_back(tmp);
return;
}
for(int i = u; i < a.size(); i++) {
if(sum + a[i] <= t) {
tmp.push_back(a[i]);
dfs(a, t, i, sum + a[i], tmp);
tmp.pop_back();
}
}
}
};
时间复杂度指数级别
空间复杂度
O
(
n
)
O(n)
O(n)
Leetcode 40
https://leetcode.com/problems/combination-sum-ii/
题意:给定一个正
整数数组,从数组中找组合,使得组合出来的数的和为t。不可以重复选,有重复数字
题解:和39类似,但是唯一不同的是有重复数字以及不可以重复选相同位置的数字,要先排序对每一层dfs中,i > u
并且a[i] == a[i-1]
可以去除重复。比如说我有[1, 1, 1, 3]数组么,target = 5, 原因是对于每一层dfs,选第一个1,和第二1或者第三个1都是一样的。所以可以直接去重复。
class Solution {
public:
vector<vector<int>> res;
vector<vector<int>> combinationSum2(vector<int>& a, int t) {
vector<int> tmp;
sort(a.begin(), a.end());
dfs(a, t, tmp, 0, 0);
return res;
}
void dfs(vector<int>& a, int t, vector<int>& tmp, int u, int sum) {
if( sum == t ) {
res.push_back(tmp);
}
for(int i = u; i < a.size(); i++) {
if(i > u && a[i] == a[i-1]) continue;
if(sum + a[i] <= t) {
tmp.push_back(a[i]);
dfs(a, t, tmp, i+1, sum + a[i]);
tmp.pop_back();
}
}
}
};
时间复杂度指数级别
空间复杂度
O
(
n
)
O(n)
O(n)
lintcode 90 K sum II 更为简单,不能选重复位置的数字,但是数组里本来就没有重复值,为leetcode 40的简化版