题目:
给你一个下标从 0 开始的整数数组 coins
,表示可用的硬币的面值,以及一个整数 target
。
如果存在某个 coins
的子序列总和为 x
,那么整数 x
就是一个 可取得的金额 。
返回需要添加到数组中的 任意面值 硬币的 最小数量 ,使范围 [1, target]
内的每个整数都属于 可取得的金额 。
数组的 子序列 是通过删除原始数组的一些(可能不删除)元素而形成的新的 非空 数组,删除过程不会改变剩余元素的相对位置。
思考:
数学推导——若目前硬币已经能组合得到[1,x]的所有整数,现在加入硬币y,那么能够组合得到的所有整数为[1,x]U[y,x+y],要使得这个结果中间没有缺少的整数且包含最多的整数,则x+1=y,也就是说,最贪心的加硬币的方式是加入的硬币y比原来能得到的连续整数最大值大1。
1. 初始化:能得到的连续整数最大值ulimit初始为0,加入硬币的数量初始为0
2. 将数组coins升序排序
3. 逐个访问coins内的硬币coin,若coin <= ulimit+1(coin加入后,可得到的整数是连续的),则增加上限,即最大值ulimit更新为原ulimit+coin;否则,增加硬币ulimit+1,并重新升序排序数组coins,更新ulimit,增加加入硬币的数量
4. 直到ulimit >= target为止
代码如下:
class Solution(object):
def minimumAddedCoins(self, coins, target):
"""
:type coins: List[int]
:type target: int
:rtype: int
"""
ulimit = 0 # 可以连续取到的[1,ulimit]的上限
result = 0
coins.sort()
i = 0
while True:
n = len(coins)
if i < n and coins[i] <= ulimit + 1: # 增加上限
ulimit += coins[i]
else: # 增加硬币
coins.append(ulimit + 1)
coins.sort()
ulimit = ulimit*2 + 1
result += 1
if ulimit >= target:
return result
i += 1
提交通过: