题目描述:给定一个候选人编号的集合 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。
注意:解集不能包含重复的组合。。
示例1:
1 2 3 4 5 6 7 8
| 输入: candidates = [10,1,2,7,6,1,5], target = 8, 输出: [ [1,1,6], [1,2,5], [1,7], [2,6] ]
|
示例2:
1 2 3 4 5 6 7
| 输入: candidates = [2,5,2,1,2], target = 5, 输出: [ [1,2,2], [5] ]
|
题解方法一:回溯+剪枝
算法思路
参考第39题
代码实现如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| function combinationSum2(candidates, target) { function backtrack(state, target, choices, start, res) { // 子集和等于 target 时,记录解 if (target === 0) { res.push([...state]); return; } // 遍历所有选择 // 剪枝二:从 start 开始遍历,避免生成重复子集 for (let i = start; i < choices.length; i++) { // 剪枝一:若子集和超过 target ,则直接结束循环 // 这是因为数组已排序,后边元素更大,子集和一定超过 target if (target - choices[i] < 0) { break; } if (i > start && choices[i] == choices[i - 1]){ continue } // 尝试:做出选择,更新 target, start state.push(choices[i]); // # 进行下一轮选择 backtrack(state, target - choices[i], choices, i+1, res); state.pop(); } } const state = []; // 状态(子集) candidates.sort((a, b) => a - b); // 对 candidates 进行排序 const start = 0; // 遍历起始点 const res = []; // 结果列表(子集列表) backtrack(state, target, candidates, start, res); return res; }
|
总结:大功告成✌️✌️✌️✌️✌️✌️✌️✌️✌️✌️✌️✌️✌️✌️✌️✌️✌️✌️✌️✌️
参考链接: