力扣 题目39-- 组合总和
题目
题解
这题一开始想投机取巧结果走了弯路 浪费了不少时间.. 呜呜呜
看见这种类似于比较大小的 先排序再说
然后我们可以这样想
每一轮从candidates中挑出一个数(从小到大)出来 每一轮的加和 和target比较
以candidates = [2,3,5], target = 8 为例
1.先拿2 2<8 继续拿
2.再拿2 2+2=4<8 继续拿
3.再拿2 2+2+2=6<8 继续拿
4.再拿2 2+2+2+2=8=target=8 正好 2,2,2,2就是答案
5.然后我们放回最后一次拿的
6.然后改拿3 2+2+2+3=9>8 大了就说明不能取 放回(因为提前排了序 后面的5肯定不能拿 所以这次我们应该放回两个了)
7.拿3 2+2+3=7<8 继续拿
8.拿3 2+2+3+3=10>8 与上面同理 此时放回两个
9.......省略.....
10.拿3 2+3+3=8=target 2,3,3就是答案
总结 大于就放回 小于就留着 等于就拿走
代码
1 #include<iostream> 2 #include<algorithm> 3 #include<vector> 4 using namespace std; 5 vector<vector<int>> binationSum(vector<int>& candidates, int target,int position,int add, vector<int> &test,vector<vector<int>> &res) 6 { //从position位置开始 因为之前遍历过的就不需要再遍历了 不然答案会重复 7 for (int i = position; i < candidates.size(); i++) { 8 //三种情况 1.小于 add是上一轮给的值 如果这个数+candidates[i]小于了 说明有可能成为解 更新一下add 继续递归 9 if (add+ candidates[i] < target) { 10 //把test作保留 11 test.push_back(candidates[i]); 12 binationSum(candidates, target, i, add + candidates[i],test, res); 13 //回溯 14 test.pop_back(); 15 } 16 //三种情况 2.等于 add是上一轮给的值 如果这个数+candidates[i]等于了 说明test加上candidates[i]就是解 直接给res 17 else if (add + candidates[i] == target) { 18 //把test作保留 19 test.push_back(candidates[i]); 20 //把test给res 21 res.push_back(test); 22 //回溯 23 test.pop_back(); 24 } 25 //三种情况 3.大于 add是上一轮给的值 如果这个数+candidates[i]大于了 说明不可能是解 并且因为之前排序了所以它之后也不可能有解 26 else 27 { 28 return {}; 29 } 30 } 31 return res; 32 } 33 class Solution { 34 public: 35 vector<vector<int>> combinationSum(vector<int>& candidates, int target) { 36 //排序!! 37 sort(candidates.begin(), candidates.end()); 38 vector<vector<int>> res; 39 vector<int> test; 40 //调用函数 直接传入引用 占用空间少 41 binationSum(candidates, target, 0, 0, test,res); 42 return res; 43 } 44 }; 45 int main() { 46 Solution sol; 47 vector<int> candidates = { 1,2 }; 48 int target = 1; 49 vector<vector<int>> res=sol.combinationSum(candidates, target); 50 for (int i = 0; i < res.size(); i++) { 51 for (int j = 0; j < res[i].size(); j++) { 52 cout << res[i][j]; 53 } 54 cout << endl; 55 } 56 }