标签:tin script 没有 for 应该 delete stack 基本 continue
给定一个数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。
candidates 中的每个数字在每个组合中只能使用一次。
说明:
示例 1:
输入: candidates = [10,1,2,7,6,1,5], target = 8,
所求解集为:
[
[1, 7],
[1, 2, 5],
[2, 6],
[1, 1, 6]
]
示例 2:
输入: candidates = [2,5,2,1,2], target = 5,
所求解集为:
[
[1,2,2],
[5]
]
var combinationSum2 = function(candidates, target) {
let _hash = {}, ret = [];
// build hash map
for (let n of candidates) {
_hash[n] = typeof _hash[n]==‘undefined‘ ? 1 : _hash[n]+1;
}
function dfs(hash, target, solution) {
if (target == 0) {
// get it
ret.push(Object.assign([], solution));
return true;
}
if (target < 0) {
return false;
}
for (let k in hash) {
if (hash[k] == 0) {continue;}
solution.push(k);
hash[k]--;
dfs(Object.assign({}, hash), target - k, solution);
// 避免重复,非常关键
delete hash[k];
solution.pop();
}
}
dfs(_hash, target, []);
return ret;
}
ac之后意外的用时击败了5%的用户,内存击败5%用户,大概这应该算是一种暴力求解,所以速度这么慢?
这是我第一次ac的方法,也是从我39题的基础上直接修改的
基本思路没有区别,只是在一些边界上稍作变化:
var combinationSum2 = function(candidates, target) {
// sort + stack
candidates.sort();
let ret = [],stack = [], i = candidates.length-1;
while (i>=0 || stack.length>0) {
if (target == 0) {
// resolved
let solution = [];
for (var k in stack) {
solution.push(candidates[stack[k]]);
}
ret.push(solution);
let pre = stack.pop();
target += candidates[pre];
// 区别1,找到题解,跳过相同数字,避免重复答案
while (candidates[i] == candidates[pre]){i--;};
continue;
} else if (i < 0) {
pre = stack.pop();
target+=candidates[pre];
i = pre - 1;
// 区别2,索引溢出,本次寻找失败,跳过相同的数字
while (i>0 && candidates[i] == candidates[pre]) {i--;}
continue;
} else if (target >= candidates[i]) {
// 区别3,入栈之后索引需要移位
stack.push(i);
target -= candidates[i];
}
i--;
}
//
return ret;
};
[leetcode 40. 组合总和 II] 不排序使用哈希表+dfs递归 vs 排序栈+回溯
标签:tin script 没有 for 应该 delete stack 基本 continue
原文地址:https://www.cnblogs.com/dapianzi/p/12704549.html