对比递归分支返回向量实现目标和最短组合与全量枚举的代码调试
递归实现目标和组合的代码问题排查
最初版findBestSum(求最短组合)的核心逻辑错误
- 跨递归作用域的共享temp设计完全错位
传入的temp是全局共享的存储容器,没有按每个递归节点的作用域隔离内容。每一层递归遍历元素时,都会把所有历史路径的组合持续往这个容器里塞,导致当前节点拿到的候选组合根本不是自身下属子分支的返回值,而是整个递归树从根到当前路径攒下的所有历史结果,完全失去了分支对比的意义。更严重的是,函数刚进入else分支时small是空向量,第一次取temp[0]做长度对比时,如果temp里还没有存入任何元素,会直接触发数组越界。 - 最短长度对比逻辑位置错误
“遍历所有候选组合找最短值”的代码被写在了for循环内部,每处理一个元素i就遍历一遍temp找最短向量。因为temp是全局共享的,找到的所谓“最短组合”其实是所有历史路径里的最短值,根本不是当前节点下属分支的结果。比如测试用例target=6、元素{2,3,5}时,走到剩余和为3的递归节点时,会直接返回长度为1的单个3,把这个值直接作为父节点的返回结果传递,根本等不到后续凑出[3,3]、[2,2,2]的其他分支遍历完成,最终自然只会输出单个3。 - 无效路径判断逻辑冗余易误判
用带-1的向量标记无效路径,判断条件同时判断向量非空、不存在-1,额外引入了不必要的find操作,也完全没考虑空向量本身就是target=0时的合法返回值,边界处理非常容易出bug。
修正方向
每个递归节点需要在自身的局部作用域内,收集当前遍历的所有元素对应的子递归返回的有效组合,给每个组合尾部加上当前元素i后,再在本地的候选集合里挑最短的组合向上传递,不要跨递归层共享全局存储容器。
更新版howSum(枚举所有有效组合)的核心逻辑错误
- 提前截断递归分支导致枚举不全
遇到第一个返回true的有效路径后,立刻执行return true,直接中断了for循环的后续遍历。比如测试用例元素顺序是{1,4,5}时,递归会顺着一直选1的路径一直走到剩余和为0,存入全1的组合后直接沿着递归栈一路return,根本不会轮到后续选4、选5的分支执行,自然只能输出第一个有效组合。 - 回溯时的向量清理时机错误
在把有效组合存入allSums后立刻对howSumVector执行clear操作,但递归栈的上层帧还在等待当前函数return后,把当前遍历的元素push进向量做组合拼接。这个clear操作会直接清空整个路径上的中间拼接结果,后续其他分支根本没法正常拼接出完整组合。 - 静态变量设计存在天然缺陷
static int originaltargetsum = targetSum;只会在第一次调用函数时完成初始化,后续所有递归调用都不会重新给这个静态变量赋值。虽然测试用例里第一次调用的target刚好等于原始值,但只要外层传入的target有变动,这个逻辑直接就会失效,属于非常脆弱的实现。 - 冗余的组合判断逻辑
额外用accumulate计算向量和判断是否等于原始target,其实递归的base case(剩余和为0)已经天然说明当前拼接的路径刚好凑满了目标和,完全不需要额外做累加和校验。
修正方向
枚举全组合时不要用提前return的bool值截断路径:当递归走到剩余和为0的base case时,直接把当前拼接的路径存入allSums;回溯返回上一层时,把当前步加入的元素从拼接向量中pop出去(标准回溯写法),保证for循环里的每个元素分支都能被完整遍历,不做提前截断。
内容的提问来源于stack exchange,提问作者Divyanshu Varma
相关产品推荐
相关产品推荐

