【每日算法】LeetCode 39 —— 组合总和 (一百三十一)

题目内容

给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。

candidates 中的数字可以无限制重复被选取。

说明:

1、所有数字(包括 target)都是正整数。
2、解集不能包含重复的组合。

示例

示例 1:

输入:candidates = [2,3,6,7], target = 7,
所求解集为:
[
[7],
[2,2,3]
]

示例 2:

输入:candidates = [2,3,5], target = 8,
所求解集为:
[
[2,2,2,2],
[2,3,3],
[3,5]
]

提示

1、1 <= candidates.length <= 30
2、1 <= candidates[i] <= 200
3、candidate 中的每个元素都是独一无二的。
4、1 <= target <= 500

题解

本题是一道求方案数量的题目,因此需要采用搜索算法。

这里采用深度优先算法,采用递归的实现方式求解。

在具体思路上,就类似于在空位中枚举数字,可见下图辅助思考。

具体请看代码注释。

代码

class Solution {
public:

vector<vector<int>> res;//设置全局结果变量
vector<int> path;//设置全局搜索路径

vector<vector<int>> combinationSum(vector<int>& cs, int target) {
dfs(cs, 0, target);//建立深度优先搜索函数
return res;
}
//cs为给出的数组,u代表当前到了数组的哪个数,target为给定的target
void dfs(vector<int>& cs, int u,int target){
if(target == 0) {
res.push_back(path); //如果target被减到了0 说明目前找到了一组解,直接返回
return;
}
if(u == cs.size()) return;//如果当前已经将整个cs遍历完,仍未得出解,直接返回。

//枚举可能的情况
for(int i = 0; cs[u] * i <= target; i++){
dfs(cs, u + 1, target - cs[u] * i);
path.push_back(cs[u]);
}
//恢复现场
for(int i = 0; cs[u] * i <= target; i++){
path.pop_back();
}
}
};
Author: Frederic Niu
Link: https://www.fredericniu.cn/2021/05/05/【每日算法】LeetCode-39-——-组合总和-(一百三十一)/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.
我的公众号