大家好,我试图理解这个组合总和的解决方案。
function combinationSum(candidates, target) {
var result = [];
if ((candidates == null) || (candidates.length == 0)) {
return result;
}
var cur = [];
candidates = candidates.sort((a, b) => a - b)
csh(candidates, target, cur, result, 0);
return result;
};
function csh(cand, target, cur, result, j) {
//console.log(cur);
if (target == 0) {
var temp = cur.slice();
result.push(temp);
return;
}
for (var i = j; i < cand.length; i++) {
if (target < cand[i]) {
return;
}
//console.log(cur);
cur.push(cand[i]);
console.log(cur);
csh(cand, target - cand[i], cur, result, i);
cur.pop();
}
}
https://leetcode.com/problems/combination-sum/description/
虽然我理解递归的基本原理,但这个问题在我身上有点丢失了。例如,对于输入:
candidates = [2,3,6,7]
target = 7
当您第一次输入函数cur
为空时,我们的第一次迭代是:
[],
[2],
[2,2]
然后我们不断添加cand[i]
,目前为2
[2,2,2]
但此时,target = 1
小于cand[i]
2
,我们将返回。自从我们返回后,我们弹出堆栈,从堆栈中弹出最后2
。自从我们返回后,我们会增加i
,然后我们将3
添加到cur
[2,2,3]
由于我们的目标数组等于0
,我们现在再次返回并且我的问题是,此时我们一直返回cur
为空并继续执行如下函数?
[2,2]
[2]
[]
[6]
[]
[7]
我只是想了解这个功能正在做什么。
答案 0 :(得分:0)
target
对于函数的每次调用都是本地的。 target
仅对函数的某些调用是0
。请注意,递归调用是:
csh(cand, target - cand[i], cur, result, i);
该范围中的target
未更改,但当前输入的csh
调用的target
值较低。当该函数返回并且程序流重新进入其他级别时,我们继续使用较高的target
值,并提供给子查询的减少值target - cand[i]
。
在将第二个元素更改为下一个元素之前,该算法还将尝试[2,2,...]
路径上的所有其他可能性。然后,它会探索[2,3,...]
空间和[2,6,...]
空间,最终探索所有[3,...]
,[6,...]
和[7,...]
种可能性。
算法总是尽可能深(即,尽可能长的数组),但不能超过原始限制。
请注意,它不会产生[2,3,2]
,因为较早的候选者不能在较晚的候选者之后出现(因此2
永远不会在结果中的3
之后。它强制执行此操作,使for
从i = j
开始,其中j
是最后一个候选使用的数组深度,因此当结果在{{}}结束时1}}候选人,它只考虑n
和更高的候选人。这具有实用价值,因为该算法仅返回每个值结果集的一个排列:n
和[2,2,3]
包含相同的值集。
答案 1 :(得分:0)
我完全理解递归可能很难理解和解释,但这是我对它的看法。
第一次调用csh时,这就是传递的内容
csh(cand,7,[],[],0)
现在来自for循环,i = 0
,被调用的函数是
csh(cand,5,[2],[],0)
,i = 0
,被调用的函数是
csh(cand,3,[2,2],[],0)
,i = 0
,被调用的函数是
csh(cand,1,[2,2,2],[],0)
,target(1) < cand[0](2)
,所以返回步骤4并从[2,2,2]中弹出最后2个,结果为[2,2]
i = 1
的,被调用的函数是
csh(cand,0,[2,2,3],[],1)
此处符合target == 0
条件。所以,[2,2,3]被推到了结果中。然后再次返回步骤4.从[2,2,3]中弹出3。
target(3) < cand[2](6)
,所以返回步骤3.并从[2,2]中弹出2,得到[2]。i = 1
的,被调用的函数是
csh(cand,2,[2,3],[[2,2,3]],1)
从循环i = 1
,target(2) < cand[1](1)
返回第9步。
所以没有...
基本上,将检查每个组合。
[2,2,2]
[2,2,3] --> added to result
[2,3,3]
[2,6]
[2,7]
[3,3,3]
[3,6]
[3,7]
[6,6]
[6,7]
[7] --> added to res