小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
说明:文章部分内容及图片出自网络,如有侵权请与我本人联系(主页有公众号:小攻城狮学前端)
作者:小只前端攻城狮、 主页:小只前端攻城狮的主页、 来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
题目描述
给定一个无重复元素的正整数数组 candidates 和一个正整数 target ,找出 candidates 中所有可以使数字和为目标数 target 的唯一组合。
candidates 中的数字可以无限制重复被选取。如果至少一个所选数字数量不同,则两种组合是唯一的。
对于给定的输入,保证和为 target 的唯一组合数少于 150 个。
示例 1:
输入: candidates = [2,3,6,7], target = 7
输出: [[7],[2,2,3]]
思路:DFS
结束条件
- 当递归的数组都被递归完了
- 当路径内的元素总和 > 目标值,
- 当路径内的元素总和 > 目标值,把路径扔到结果数组里
如果都没有到出递归的条件,就循环当前的数组,每次都进入 dfs,拼新的数组(数组的内容是从当前循环的 i 开始,直到数组结束)并传入,并拼接新的 path
var combinationSum = function(candidates, target) {
const res = []
function dfs (arr, path) {
if (arr.length === 0) {
return
}
const currAdd = path.reduce((curr, add) => curr + add, 0)
if (currAdd > target) {
return
}
if (currAdd === target) {
res.push(path)
}
for (let i = 0; i < arr.length; i++) {
dfs(arr.slice(i, arr.length), [...path, arr[i]])
// 拼接新的 arr, i - arr.length 是为了把已经选过的 arr 的值排除掉。 拼接新的 path
}
}
dfs(candidates, [], 0)
return res
};
优化:DFS+剪枝
var combinationSum = function (candidates, target) {
var resultList = [];
var combin = function (value, path) {
if (value === 0) return resultList.push(path.slice());
if (value < 0) return;
for (var i = 0; i < candidates.length; i++) {
if (path.length === 0 || (path.length > 0 && path[path.length - 1] >= candidates[i])) {
var minus = value - candidates[i];
path.push(candidates[i]);
combin(minus, path);
path.pop(candidates[i]);
}
}
};
combin(target, []);
return resultList;
};
总结:加了剪枝,性能上提升不少呀。
感谢阅读,希望能对你有所帮助,文章若有错误或者侵权,可以在评论区留言或在我的主页添加公众号联系我。
写作不易,如果觉得不错,可以「点赞」+「评论」 谢谢支持❤