动态规划疑问:拆分if语句后求最小硬币数的代码为何失效?
Min-Change问题拆分复合if语句后逻辑失效的原因分析
我在解决Min-Change问题时遇到一个逻辑问题:给定硬币数组和目标金额,返回凑成目标金额所需的最少硬币数量。我用递归思路实现,其中islandSize记录最终要返回的最少硬币数,currentSize记录递归路径中当前凑成对应金额的硬币数。
原代码中使用复合if语句可以正常工作,但将其拆分为两个独立if语句后,代码运行异常。我原本认为两种写法逻辑等价,但实际结果不符,希望有人指出错误。
工作代码片段(复合if版本)
function minChange(coins, amount) { let islandSize = -1; function helper(remaining) { if (remaining === 0) return 0; if (remaining < 0) return -1; let minCoins = -1; for (let coin of coins) { const res = helper(remaining - coin); if (res !== -1) { const currentSize = res + 1; // 复合if语句 if (currentSize !== -1 && (islandSize === -1 || currentSize < islandSize)) { islandSize = currentSize; } } } return minCoins; } helper(amount); return islandSize; }
失效代码片段(拆分if版本)
// 拆分后的失效代码 function minChange(coins, amount) { let islandSize = -1; function helper(remaining) { if (remaining === 0) return 0; if (remaining < 0) return -1; let minCoins = -1; for (let coin of coins) { const res = helper(remaining - coin); if (res !== -1) { const currentSize = res + 1; // 拆分后的两个独立if if (currentSize !== -1 && islandSize === -1) { islandSize = currentSize; } // 错误:缺少currentSize !== -1的判断 if (currentSize < islandSize) { islandSize = currentSize; } } } return minCoins; } helper(amount); return islandSize; }
问题核心
拆分后的第二个if语句缺少了currentSize !== -1的前置判断。当递归过程中出现currentSize为-1的情况(比如某些路径无法凑出剩余金额),此时currentSize < islandSize可能会成立(例如islandSize已经是一个正数,-1必然小于正数),导致islandSize被错误地设置为-1,覆盖了之前找到的有效最少硬币数,最终返回错误结果。
原复合if语句中,currentSize !== -1是全局前置条件,确保只有有效路径才会触发后续判断。拆分后必须在每个独立if中都保留这个前置条件,否则会引入无效路径的干扰。
修正后的拆分代码
// 正确拆分后的代码 function minChange(coins, amount) { let islandSize = -1; function helper(remaining) { if (remaining === 0) return 0; if (remaining < 0) return -1; let minCoins = -1; for (let coin of coins) { const res = helper(remaining - coin); if (res !== -1) { const currentSize = res + 1; if (currentSize !== -1 && islandSize === -1) { islandSize = currentSize; } // 补充currentSize !== -1的判断 if (currentSize !== -1 && currentSize < islandSize) { islandSize = currentSize; } } } return minCoins; } helper(amount); return islandSize; }
提问方式改进建议
- 补充完整代码片段:尽可能提供可复现的最小代码示例,包括变量初始化、递归逻辑的完整上下文,方便他人快速定位问题。
- 明确错误表现:说明代码运行后的具体异常结果(比如返回-1、返回错误的硬币数、超时等),而不仅仅说“无法正常工作”。
- 标注语言类型:明确说明代码使用的编程语言(如JavaScript、Python),避免歧义。
内容的提问来源于stack exchange,提问作者fwan
相关产品推荐
相关产品推荐

