LeetCode——零钱兑换

题目描述:

给定不同面额的硬币 coins 和一个总金额 amount。编写一个函数来计算可以凑成总金额所需的最少的硬币个数。如果没有任何一种硬币组合能组成总金额,返回 -1。

示例 1:
输入: coins = [1, 2, 5], amount = 11
输出: 3
解释: 11 = 5 + 5 + 1

示例 2:
输入: coins = [2], amount = 3
输出: -1

说明:
你可以认为每种硬币的数量是无限的。

来源:力扣(LeetCode)
链接:零钱兑换

思路:

对于这道题,我一开始的想法就是贪心算法。因为每次是要组成总金额所需硬币数最少,所以每次需要优先选面值大的硬币,如果面值过大,则选择次之,以此循环下去。先将coins从小到大进行排序,然后从coins的最后一个元素开始往前移动,当剩余的总金额比当前所选的硬币面值大,则剩余总金额减去当前的硬币面值,然后以当前所处的coins中的位置 i 保持不变,如此循环;而当剩余的总金额等于当前所选的硬币面值,则需要比较硬币数量,如果当前的硬币数量比存放最少硬币数量的变量要小,则替换掉当前存放最少硬币数量的变量;当剩余总金额小于当前所选的硬币面值,则coins中的 i 往前移动,如果判断完coins数组中的全部面值,则需要进行回溯,当前剩余总金额回溯到前一个状态然后再次进行判断选择。
以上就是对于这道题贪心算法的大致过程,但是,做完这些提交完之后,会发现时间超限了,这时需要进行代码的优化,其实也就是剪枝操作,具体如何剪枝,需要通过分析获得,相对来说,这道题的剪枝操作不算难,只需要在递归过程中判断当前的硬币数量是否比存放最少硬币数量的变量大,如果比其大,则停止递归,返回上一层,因为当前硬币数量已经大过最少硬币数量了,再继续递归下去将没有意义,到最后比较该值还是会进行舍弃;还有一个剪枝操作则是利用剩余总金额除去当前所选的硬币面值向下取整,再加上当前的硬币数量,对比存放最少硬币数量的变量,如果比其大,则停止递归,返回上一层,因为如果当前面值的硬币是所能选择的硬币中面值最大的,所以如果当前硬币要凑成剩余总金额的个数与之前所选的硬币个数之和比最少硬币数量大,则说明没有继续递归下去的意义,递归到最后该值如果能成立,肯定会比最少硬币数量要大,会被舍弃。通过这两步剪枝后,代码的效率会提升很多。

具体代码:

int min = 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值