[leetcode 40. 组合总和 II] 不排序使用哈希表+dfs递归 vs 排序栈+回溯
2021-02-16 15:23
标签:tin script 没有 for 应该 delete stack 基本 continue 给定一个数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。 candidates 中的每个数字在每个组合中只能使用一次。 说明: 示例 1: 示例 2: ac之后意外的用时击败了5%的用户,内存击败5%用户,大概这应该算是一种暴力求解,所以速度这么慢? 这是我第一次ac的方法,也是从我39题的基础上直接修改的 [leetcode 40. 组合总和 II] 不排序使用哈希表+dfs递归 vs 排序栈+回溯 标签:tin script 没有 for 应该 delete stack 基本 continue 原文地址:https://www.cnblogs.com/dapianzi/p/12704549.html题目描述
输入: candidates = [10,1,2,7,6,1,5], target = 8,
所求解集为:
[
[1, 7],
[1, 2, 5],
[2, 6],
[1, 1, 6]
]
输入: candidates = [2,5,2,1,2], target = 5,
所求解集为:
[
[1,2,2],
[5]
]
方法一 不排序使用哈希表+dfs递归
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
方法二 排序栈+回溯
基本思路没有区别,只是在一些边界上稍作变化: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 && 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 排序栈+回溯
文章链接:http://soscw.com/index.php/essay/56153.html