leetcode-2024-3-30
2952 需要添加的硬币的最小数量(Medium)
这道题止中等?
给你一个下标从 0 开始的整数数组 coins,表示可用的硬币的面值,以及一个整数 target 。
如果存在某个 coins 的子序列总和为 x,那么整数 x 就是一个 可取得的金额 。
返回需要添加到数组中的 任意面值 硬币的 最小数量 ,使范围 $[1, target]$ 内的每个整数都属于 可取得的金额 。
数组的 子序列 是通过删除原始数组的一些(可能不删除)元素而形成的新的 非空 数组,删除过程不会改变剩余元素的相对位置。
示例 1:
输入:coins = [1,4,10], target = 19
输出:2
解释:需要添加面值为 2 和 8 的硬币各一枚,得到硬币数组 [1,2,4,8,10] 。
可以证明从 1 到 19 的所有整数都可由数组中的硬币组合得到,且需要添加到数组中的硬币数目最小为 2 。
自己想没想出来
官方解:贪心算法
为方便描述,把 0也算作可以得到的数。
假设现在得到了区间 $[0,s−1]$ 中的所有整数,如果此时遍历到整数 $x=coins[i]$,那么把 $[0,s−1]$ 中的每个整数都增加 x,我们就得到了区间 $[x,s+x−1]$ 中的所有整数。
把 coins 从小到大排序,遍历 $x=coins[i]$。分类讨论,看是否要添加数字:
- 如果 x≤s,那么合并 $[0,s−1]$ 和 $[x,s+x−1]$这两个区间,我们可以得到 $[0,s+x−1]$ 中的所有整数。
- 如果 x>s,或者遍历完了 coins 数组,这意味着我们无法得到 s,那么就一定要把 s 加到数组中(加一个比 s 还小的数字就没法得到更大的数,不够贪),这样就可以得到了 $[s,2s−1]$ 中的所有整数,再与 $[0,s−1]$ 合并,可以得到 $[0,2s−1]$ 中的所有整数。然后再考虑 x 和 2s 的大小关系,继续分类讨论。
当 s>targets 时,我们就得到了 $[1,target]$ 中的所有整数,退出循环。
1 | class Solution { |