https://leetcode-cn.com/problems/combination-sum/
解题:? min (下次补上)
题解:10 min
给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。
candidates 中的数字可以无限制重复被选取。
说明:
很是撒比,之前会做的题,现在不会去重,用了set,结果慢的一匹,醉了。
其实每次不用从头找,从当前元素开始往后找就行,因为之前的各种情况都搜过了,再从头找也是重复的。而如果直接每次从当前元素开始往后找,每种情况都是全新的,还不用去重了!!!
基本思路就是暴搜,当前 数组的和 达到 目标值的话记录进结果,大于 目标值说明不行,直接舍弃。
时间复杂度:不会算
class Solution {
private:
int n, target;
set<vector<int>> ans;
public:
void dfs(int res, vector<int> tmp, vector<int>& candidates) {
if(res > target) return ;
if(res == target) {
sort(tmp.begin(), tmp.end());
ans.insert(tmp);
return ;
}
for(int i = 0; i < n; ++i) {
tmp.push_back(candidates[i]);
dfs(res+candidates[i], tmp, candidates);
tmp.pop_back();
}
}
vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
this->target = target;
n = candidates.size();
dfs(0, {
}, candidates);
vector<vector<int>> vans;
for(auto x : ans) {
vans.push_back(x);
}
return vans;
}
};
class Solution {
private:
vector<vector<int>> ans;
vector<int> path;
vector<int> candidates;
int target;
public:
vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
this->candidates = candidates;
this->target = target;
sort(this->candidates.begin(), this->candidates.end());
core(0, 0);
return ans;
}
void core(int sum, int pre) {
// for(int i = 0; i < candidates.size(); ++i) {
// cout<
// }cout<
// for(int i = 0; i < tmp.size(); ++i) {
// cout<
// }cout<
if(sum == target) {
ans.push_back(path);
return ;
}
for(int i = pre; i < candidates.size() && sum + candidates[i] <= target; ++i) {
// 这里有一个优化排序后,按顺序取,如果当前值都大于 target, 那么后面的值就不用试了
path.push_back(candidates[i]);
core(sum+candidates[i], i);
path.pop_back();
}
}
};