本题是一道使用回溯法进行搜索的典型问题,从左到右搜索数组中的元素看是否能凑出 target 的值即可。注意每次进入递归要从当前元素开始向后搜索,而不是从 candidates 数组开头向后搜索,否则会重复计算组合。
class Solution { public: vector<vector<int>> combinationSum(vector<int>& candidates, int target) { n = candidates.size(); temp_sum = 0; this->target = target; dfs(candidates, 0); return res; } vector<vector<int>> res; vector<int> temp; int temp_sum; int n; int target; void dfs(vector<int>& candidates, int j) { if(temp_sum > target) { //当temp的数组和大于目标时,直接return return; } else if(temp_sum == target) { //当temp的数组和等于目标(即找到一个排列)时,将结果插入res数组 res.push_back(temp); return; } for(int i = j; i < n; i ++) { //这边设置从索引j开始搜索,若从0(即从头)开始搜索会出现重复组合的情况(如2,2,3和2,3,2均将视为答案存储) temp.push_back(candidates[i]); temp_sum += candidates[i]; dfs(candidates, i); temp_sum -= temp.back(); //本行和下一行即为回溯的过程,将当前的数从temp删除以便搜索新的数 temp.pop_back(); } } };