【代码随想录day 22】 力扣 39. 组合总和
视频讲解:https://www.bilibili.com/video/BV1KT4y1M7HJ/?vd_source=a935eaede74a204ec74fd041b917810c
文档讲解:https://programmercarl.com/0039.%E7%BB%84%E5%90%88%E6%80%BB%E5%92%8C.html#%E6%80%9D%E8%B7%AF
力扣题目:https://leetcode.cn/problems/combination-sum/
在这道题中,有几个难点,1.数组元素可以重复选择 2.返回结果不能有重复
因此这就带来一定的困难,所以我们要注意以下几点:
- 可以重复选择的话,选择一个元素后剩下的选择仍然是数组的全部
- 返回结果不能有重复的话,我们不会再往前去遍历元素
因此在深入树的过程中,我们可选的范围是当前元素之后的所有元素(包含当前元素),如选择2后,可选范围为253,选择5后可选范围为53,选择3后,可选范围为3。
还有一个注意的点就是剪枝,可以提升效率,我们可以把数组排列成有序的数组,如果在回溯过程中sum和大于target,那么这一层以及之后的都不用看了,肯定大于target,直接return就好。
class Solution {
private:vector<vector<int>> result;vector<int> path;void backtracking(vector<int>& candidates, int target, int sum, int startIndex){//判断终止条件if(sum > target) return;if(sum == target){result.push_back(path);return;}//开始遍历for(int i = startIndex; i<candidates.size(); i++){//计算sumsum = sum + candidates[i];if(sum > target) return;//存入路径path.push_back(candidates[i]);//回溯遍历,因为从该路径自身到结尾可以继续遍历,所以从i开始回溯遍历backtracking(candidates, target, sum, i);//回溯完成,还原sum,弹出pathsum = sum - candidates[i];path.pop_back();}}
public:vector<vector<int>> combinationSum(vector<int>& candidates, int target) {//初始化数组result.clear();path.clear();//排序数组sort(candidates.begin(), candidates.end());backtracking(candidates, target, 0, 0);return result;}
};