编写JavaScript函数:按指定面额拆分金额为指定数量的组合
实现思路与代码
问题分析
要解决这个问题,核心是找到pcs个属于指定面额数组的数值,使其总和恰好等于price。先通过可行性预校验过滤不可能的情况,再用贪心策略构建符合要求的数组:
可行性校验
- 所有面额都是1000的倍数,因此
price必须能被1000整除,否则直接返回空数组 price需满足:1000 * pcs ≤ price ≤ 100000 * pcs(最小总和是pcs张1000,最大总和是pcs张100000),不满足则返回空数组
- 所有面额都是1000的倍数,因此
简化计算
将所有数值除以1000,面额数组转为[100, 50, 20, 10, 5, 2, 1],price转为price / 1000,简化后计算更便捷,最后再将结果乘1000还原。贪心构建数组
- 初始化一个全为1(对应原面额1000)的数组,长度为
pcs - 计算需要额外分配的差值
diff = 简化后的price - pcs - 遍历数组元素,从最大面额开始尝试,将当前元素提升到尽可能大的合法面额,同时消耗差值,直到差值为0
- 最后验证数组总和是否符合要求,符合则还原数值返回,否则返回空数组
- 初始化一个全为1(对应原面额1000)的数组,长度为
代码实现
function splitPrice(price, pcs) { const denominations = [100000, 50000, 20000, 10000, 5000, 2000, 1000]; const minDenom = 1000; const maxDenom = 100000; // 初步可行性校验 if (price % minDenom !== 0) return []; const minTotal = minDenom * pcs; const maxTotal = maxDenom * pcs; if (price < minTotal || price > maxTotal) return []; // 简化数值,除以1000 const priceDiv = price / minDenom; const denomsDiv = denominations.map(d => d / minDenom).sort((a, b) => b - a); // 降序排列 let result = new Array(pcs).fill(1); let remainingDiff = priceDiv - pcs; if (remainingDiff === 0) { return result.map(num => num * minDenom); } // 遍历每个元素,尽量提升到最大面额 for (let i = 0; i < result.length && remainingDiff > 0; i++) { for (const d of denomsDiv) { if (d > result[i] && (d - result[i]) <= remainingDiff) { const add = d - result[i]; result[i] = d; remainingDiff -= add; break; } } } // 最后验证总和是否正确 const total = result.reduce((sum, num) => sum + num, 0); if (total === priceDiv && remainingDiff === 0) { return result.map(num => num * minDenom); } else { return []; } } // 测试示例 console.log(splitPrice(40000, 4)); // [10000, 10000, 10000, 10000] console.log(splitPrice(10000, 4)); // [5000, 2000, 2000, 1000] console.log(splitPrice(40000, 2)); // [20000, 20000] console.log(splitPrice(50000, 2)); // []
代码说明
- 可行性校验提前过滤无效场景,减少不必要的计算
- 简化数值后,贪心策略优先给每个元素分配最大合法面额,快速消耗差值的同时保证元素合规
- 最终验证步骤确保结果完全符合要求,避免极端情况导致的错误
内容的提问来源于stack exchange,提问作者Ervan Rahadian Hakim
相关产品推荐
相关产品推荐

