法1:回溯
想法:
- 将candidates降序排列,当前数字大于target,则不使用该数字作为组合的第一个数字(跳过该数字)
- 遇到一个数字<=target,则对小于等于它的剩余数字进行组合,使得组合的和等于新的target,即target-该数字
/**
* @param {number[]} candidates
* @param {number} target
* @return {number[][]}
*/
var combinationSum = function(candidates, target) {
var output = [], temp = [];
// 将candidates中数字降序排列
candidates.sort(function(a, b) {return b - a;});
var i = 0;
for(i = 0; i < candidates.length; i++) {
if(candidates[i] > target) {
// 当前数字大于target,则含有该数字的组合不可能是结果
continue;
}
temp.push(candidates[i]);
doCombinationSum(candidates.slice(i), target - candidates[i], temp, output);
temp.pop();
}
return output;
};
function doCombinationSum(candidates, target, temp, output) {
if(target == 0) { // temp中数字和满足条件
output.push(temp.concat([]));
return;
}
var i = 0;
for(i = 0; i < candidates.length; i++) {
if(candidates[i] > target) {
// 当前数字大于target,则含有该数字的组合不可能是结果
continue;
}
temp.push(candidates[i]);
doCombinationSum(candidates.slice(i), target - candidates[i], temp, output);
temp.pop();
}
}