← 返回编程题库
coding-greedy-coin-change-canonical-set简单免费版2000ms未尝试

规范币集上的贪心找零

Greedy Coin Change on a Canonical Denomination Set

开始编码

给定非负整数 amount 与一组互不相同的正整数面值 coin_denominations,调用方保证该集合是规范的(即降序贪心给出最少硬币数的最优解)。实现 solution(amount: int, coin_denominations: list[int]) -> list[list[int]],返回贪心分解结果——[coin, count] 列表,按面值降序排列,并省略 count == 0 的硬币。

算法就是把面值降序排好后扫一遍:每种 coincount = remaining // coin,若 count > 0 就把 [coin, count] 加进结果,然后从 remaining 中减去 coin * count。因为面值集中含 1,循环结束时 remaining 必为 0。校验:coin_denominations 含重复元素抛 ValueErrorcoin_denominations1ValueError(否则某些 amount 无法表示)。

例如,solution(37, [1, 5, 10, 25, 100]) 返回 [[25, 1], [10, 1], [1, 2]]:37 // 25 = 1 余 12,12 // 10 = 1 余 2,2 // 5 = 0(跳过),2 // 1 = 2。自定义规范集 {1, 4, 16} 同理:solution(21, [1, 4, 16]) 返回 [[16, 1], [4, 1], [1, 1]]。退化情形单一面值就只能用 1 凑:solution(7, [1]) 返回 [[1, 7]]。空 amount 返回空:solution(0, [1, 5, 10, 25, 100]) 返回 []

关于规范性的注意。 贪心并非对所有面值集合都最优。对 {1, 3, 4}amount = 6:贪心给 4 + 1 + 1(3 枚),最优是 3 + 3(2 枚)。约束里写"币集是规范的",是把验证责任交给调用方;本函数不做规范性校验。规范集的常见例子有美元面值 {1, 5, 10, 25, 100}、以及任何"后一个币是前一个整数倍"的几何递增集(例如 {1, 4, 16})。

实践背景

执行算法里的现金分配子程序,本质上是同一个问题:给定要部署的目标名义量与一组允许的切片大小(clip size),把目标拆分成尽可能少的切片,让送往交易所的子单数最少(每条子单都有固定费用与每秒消息速率配额)。当切片菜单是规范的——典型如 {1, 10, 100, 1000} 股的粗到细阶梯——降序贪心就给出最少切片的最优拆分,时间线性。生产环境里的 sizing helper 在每次接到母单时都会调用这种例程,无需任何预计算。[coin, count] 这种形状正对应下游 child-order 生成器消费的 (clip_size, num_clips)。把它视为"在 sizing 规则确定阶梯之后,每种切片送多少条"这一问题的可执行内核即可。

约束条件

  • `0 <= amount <= 10**4`
  • `1 <= len(coin_denominations) <= 10`
  • 每个 `coin > 0`。`coin_denominations` 出现重复元素抛 `ValueError`。
  • `coin_denominations` 中必须包含 `1`(保证任意 amount 都可表示),否则抛 `ValueError`。
  • 调用方保证币集是**规范的**(贪心最优)。参考实现不校验规范性。
  • 返回 `list[list[int]]`,每项 `[coin, count]`,按**面值降序**排列,且省略 `count == 0` 的硬币。`amount = 0` 时返回 `[]`。

样例

Case 1 · statement-example: US set 37 cents

输入: [37,[1,5,10,25,100]]

期望: [[25,1],[10,1],[1,2]]

降序贪心:37 // 25 = 1 余 12;12 // 10 = 1 余 2;2 // 5 = 0;2 // 1 = 2。略去 0 计数后输出 [[25,1],[10,1],[1,2]]。

Case 2 · statement-example: amount=0 returns empty list

输入: [0,[1,5,10,25,100]]

期望: []

amount=0 时无需任何硬币,按零计数过滤后返回空列表 []。

Case 3 · statement-example: custom canonical {1, 4, 16} for 21

输入: [21,[1,4,16]]

期望: [[16,1],[4,1],[1,1]]

{1, 4, 16} 是规范集合(每个币是前一个的整数倍):21 = 16 + 4 + 1,按降序输出 [[16,1],[4,1],[1,1]]。

最近提交

还没有提交记录。

编码区

实现 solution(...)。本地运行当前支持 Python 可见样例;服务端提交会运行可见样例和隐藏测试。

加载编辑器...
计时0:00

默认展示公开样例。点击「运行样例」后会在这里显示实际输出;点击「提交评测」会进入隐藏测试。

Case 1 · statement-example: US set 37 cents

输入: [37,[1,5,10,25,100]]

期望: [[25,1],[10,1],[1,2]]

降序贪心:37 // 25 = 1 余 12;12 // 10 = 1 余 2;2 // 5 = 0;2 // 1 = 2。略去 0 计数后输出 [[25,1],[10,1],[1,2]]。

Case 2 · statement-example: amount=0 returns empty list

输入: [0,[1,5,10,25,100]]

期望: []

amount=0 时无需任何硬币,按零计数过滤后返回空列表 []。

Case 3 · statement-example: custom canonical {1, 4, 16} for 21

输入: [21,[1,4,16]]

期望: [[16,1],[4,1],[1,1]]

{1, 4, 16} 是规范集合(每个币是前一个的整数倍):21 = 16 + 4 + 1,按降序输出 [[16,1],[4,1],[1,1]]。