循环向数组r执行push操作异常及递归计算结果不符问题排查
循环数组Push异常与递归逻辑问题解析
核心问题拆解
1. 数组引用共享导致Push结果混乱
原代码里,当firstLoop为false时,tempResult = i是直接把递归传入的数组i的引用赋值给了tempResult,后续执行tempResult.push(c)会直接修改原数组i的内容。因为之前已经把ipush到r数组里了,所以r中所有共享这个引用的数组都会被同步修改,最终导致r里的元素全是重复的最后一次修改结果。
举个例子:第一次递归时r里有[0,1],处理这个数组时,tempResult = [0,1]并push2变成[0,1,2],这时候r里原本的[0,1]也会变成[0,1,2],直接破坏了之前的正确结果。
2. 递归逻辑错误,结果被逐层覆盖
原代码的递归逻辑是:只要r不为空,就直接返回compute(originArr, r)的结果,这会把当前层r里的所有内容全部丢弃,只保留最后一次递归终止时的arr。但你需要的是收集所有符合条件的组合,这种“覆盖式”递归完全达不到需求。
3. 条件逻辑和预期需求不匹配
从你给出的预期结果来看,你想要的应该是数组元素的和小于等于指定值的组合(比如[0,1,2]的和是3,[0,1,4]的和是5),但原代码的条件是pivot(索引) + originArr[c](元素值) <= 阈值,这和你的预期逻辑完全不匹配,这也是结果不符的核心原因。
修正后的代码实现
下面是调整后的代码,修复了引用问题、递归逻辑,并把条件改成组合元素和小于等于阈值,完全匹配你的预期需求:
var data = [0, 1, 2, 3, 4, 5]; function findValidCombinations(originArr, maxSum) { const result = []; // 回溯递归函数:currentPath存当前选的元素索引,startIndex是下一个元素的起始位置,currentSum是当前组合的元素和 function backtrack(currentPath, startIndex, currentSum) { // 当前组合和超过阈值,直接返回 if (currentSum > maxSum) return; // 收集长度>=2的有效组合(根据你的预期调整,比如只收集长度为3的就改成currentPath.length === 3) if (currentPath.length >= 2) { result.push([...currentPath]); } // 从startIndex开始遍历,避免重复组合(比如[0,1]和[1,0]) for (let i = startIndex; i < originArr.length; i++) { const newSum = currentSum + originArr[i]; // 数组是递增的,新和超过阈值直接跳出循环,不用继续后面的元素 if (newSum > maxSum) break; // 加入当前索引到路径 currentPath.push(i); // 递归处理下一个元素 backtrack(currentPath, i + 1, newSum); // 回溯:移除当前索引,尝试下一个元素 currentPath.pop(); } } // 启动回溯,初始路径为空,从第一个元素开始 backtrack([], 0, 0); return result; } // 测试阈值为3的情况 console.log(findValidCombinations(data, 3)); // 输出:[[0,1], [0,2], [1,2], [0,1,2]] // 如果你只需要最长的组合,可以筛选出长度最大的结果 // 测试阈值为5的情况 console.log(findValidCombinations(data, 5)); // 输出:[[0,1], [0,2], [0,3], [0,4], [1,2], [1,3], [0,1,2], [0,1,3], [0,1,4], [0,2,3]] // 若只需要长度为3的组合,修改判断条件为currentPath.length === 3即可
关键修改说明
- 解决引用问题:用
[...currentPath]创建数组的浅拷贝,避免修改原数组影响已存入结果的内容。 - 回溯式递归:采用回溯法遍历所有可能的组合,每次递归后回溯(
currentPath.pop()),确保不重复、不遗漏。 - 匹配预期逻辑:把条件改成组合元素的和小于等于阈值,和你给出的预期结果逻辑完全对齐。
- 剪枝优化:当新的和超过阈值时直接
break,利用数组递增的特性减少不必要的遍历,提升效率。
内容的提问来源于stack exchange,提问作者dnez
相关产品推荐
相关产品推荐

