关于canSum函数中targetSum为0返回true的逻辑疑问
问题背景
题目要求:实现函数canSum(targetSum, numbers),接收targetSum和数字数组作为参数,返回布尔值表示是否可用数组中的数字(可重复使用)生成targetSum,所有数字均为非负数。
遇到的困惑
我在观看动态规划视频时看到如下递归解法:
const canSum = (targetSum, numbers) => { if (targetSum === 0) return true; if (targetSum < 0) return false; for (let num of numbers) { const remainder = targetSum - num; if (canSum(remainder, numbers) === true) { return true; } } return false; }
我理解该代码在多数场景下的运行逻辑,比如canSum(7, [2, 3]),但无法理解if (targetSum === 0) return true;这行代码——这意味着canSum(0, [2, 3])会返回true,而我认为这不符合题目要求。
测试案例
console.log(canSum(7, [2, 4]))
返回结果为false;
console.log(canSum(0, [2]))
返回结果为true。
希望有人能为我解惑,我到底忽略了什么?
解惑
这行代码是递归的基准条件,本质是数学上的合理约定:「用0个数字相加就能得到0」,这是递归分解问题的核心前提。
举个实际例子,计算canSum(3, [3])时,代码会算出remainder = 3 - 3 = 0,接着调用canSum(0, [3])。此时返回true,代表「选了数字3之后,剩下需要凑的0可以通过选0个数字完成」,所以整体结果为true,完全符合题目要求。
至于单独调用canSum(0, [2])返回true的情况,是这类组合问题的通用边界约定:如果目标和本身就是0,不需要选任何数字就能达成,因此结果为true。没有这个基准条件,递归无法终止,也无法正确判断「刚好凑完目标和」的场景——比如canSum(3, [3])会因为最后减到0后没有正确返回值,继续递归到负数分支,最终返回错误的false。
简单来说:
- 当
targetSum减到0时,说明前面选的数字总和正好等于原始目标和,因此返回true。 - 这个逻辑是递归解法能正常工作的必要基础,并非不符合题目要求。
内容的提问来源于stack exchange,提问作者ian.thecheesestomper

