题目二:
解法一:(回溯)
解题思路:这道题,主要就是要去除重复的结果组合,参考代码随想录。
这个题的“去重”,主要是同一树层维度上的去重,而不是同一树枝维度上的去重。
var combinationSum2 = function(candidates, target) {
const res = []; path = [], len = candidates.length;
candidates.sort((a,b)=>a-b);
backtracking(0, 0);
return res;
function backtracking(sum, startIndex) {
if (sum === target) {
res.push(Array.from(path));
return;
}
for(let i = startIndex; i < len; i++) {
const n = candidates[i];
if(i > startIndex && candidates[i] === candidates[i-1]){
//若当前元素和前一个元素相等
//则本次循环结束,防止出现重复组合
continue;
}
//如果当前元素值大于目标值-总和的值
//由于数组已排序,那么该元素之后的元素必定不满足条件
//直接终止当前层的递归
if(n > target - sum) break;
path.push(n);
sum += n;
backtracking(sum, i + 1);
path.pop();
sum -= n;
}
}
};
但其实自己写的代码,加上一行代码就可以了。
if (i > startIndex && candidates[i] === candidates[i - 1]) continue
完整代码:
var combinationSum2 = function(candidates, target) {
let result = []
let path = []
candidates.sort((a, b) => a - b)
const backtracking = function(sum, startIndex) {
if (sum > target) return
if (sum === target) {
result.push([...path])
return
}
for (let i = startIndex; i < candidates.length; i++) {
if (i > startIndex && candidates[i] === candidates[i - 1]) continue
path.push(candidates[i])
sum += candidates[i]
backtracking(sum, i + 1)
path.pop()
sum -= candidates[i]
}
}
backtracking(0, 0)
return result
};
解法二:(used)
var combinationSum2 = function(candidates, target) {
let res = [];
let path = [];
let total = 0;
const len = candidates.length;
candidates.sort((a, b) => a - b);
let used = new Array(len).fill(false);
const backtracking = (startIndex) => {
if (total === target) {
res.push([...path]);
return;
}
for(let i = startIndex; i < len && total < target; i++) {
const cur = candidates[i];
if (cur > target - total || (i > 0 && cur === candidates[i - 1] && !used[i - 1])) continue;
path.push(cur);
total += cur;
used[i] = true;
backtracking(i + 1);
path.pop();
total -= cur;
used[i] = false;
}
}
backtracking(0);
return res;
};