You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

JavaScript找零函数优化求助:基于$2、$5、$10纸币的最优实现

最优找零方案:$2、$5、$10面额的贪心解法

嘿,刚学JS碰到这种问题太正常了!我当初入门的时候也在类似的贪心问题上踩过坑,不过咱们这个面额组合刚好完美适配贪心算法——毕竟不是所有面额都能用贪心,但$2、$5、$10这组的特性决定了「优先用大面额」就是最优解,给你一步步拆解:

核心思路:贪心选择的合理性

因为$10是最大面额,每张抵10块,能最快减少找零金额;其次是$5,最后是$2。不过要注意一个特殊情况:奇数金额必须用至少一张$5(毕竟只有$5是奇数,$2和$10都是偶数,奇数=奇数+偶数,所以先拿一张$5,剩下的就变成偶数,就能用$2和$10凑了)。

具体步骤

  • 合法性校验
    • 找零金额小于$2?直接返回无法找零(最小面额是$2)
    • 如果是奇数金额且小于$5?也没法找零(比如$3,凑不出来)
  • 处理奇数金额:如果金额是奇数,先减去$5,张数+1,剩下的金额变成偶数
  • 优先用$10:计算能拿多少张$10,张数加上这个数量,剩下的金额减去对应总额
  • 用$2凑剩余:剩下的偶数金额直接除以2,得到$2的张数,加到总张数里

JavaScript代码实现

function calculateMinChange(amount) {
  // 先判断基础合法性
  if (amount < 2) {
    return "无法完成找零(金额过小)";
  }
  
  let totalNotes = 0;
  let remaining = amount;

  // 处理奇数金额的特殊情况
  if (remaining % 2 !== 0) {
    if (remaining < 5) {
      return "无法完成找零(无法用现有面额组合)";
    }
    remaining -= 5;
    totalNotes += 1;
  }

  // 优先使用最大面额$10
  const tenCount = Math.floor(remaining / 10);
  totalNotes += tenCount;
  remaining -= tenCount * 10;

  // 剩余偶数金额用$2凑
  const twoCount = remaining / 2;
  totalNotes += twoCount;

  return `最少需要${totalNotes}张纸币`;
}

测试用例验证

  • 输入10 → 返回「最少需要1张纸币」(1张$10)
  • 输入15 → 返回「最少需要2张纸币」(1张$10 + 1张$5)
  • 输入7 → 返回「最少需要2张纸币」(1张$5 + 1张$2)
  • 输入8 → 返回「最少需要4张纸币」(4张$2,没有更优的组合)
  • 输入3 → 返回「无法完成找零(无法用现有面额组合)」

为什么这个解法是最优的?因为对于这个面额组合,贪心选择不会出现「为了省一张大面额,导致后续需要更多小面额」的情况。比如找$14,贪心用$10+$2+$2(3张),如果硬要用$5+$5+$2+$2(4张)反而更多,所以贪心完全可行。

内容的提问来源于stack exchange,提问作者Platiplus

火山引擎 最新活动