LeetCode322,硬币凑整问题

LeetCode 322

问题描述

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

示例 1:

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

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

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/coin-change

解题思路

这道题,可以采用多种方式来解决。这里使用动态规划来解题。首先,找出状态转移方程。

  1. 已知硬币面值coins[],用这些硬币凑成指定的金额amount。要求硬币个数最少。
  2. 设金额amount对应的最少硬币个数为:f(amount)
  3. 自上而下推,我们可以这样想,金额amount对应的最少硬币数f(amount),肯定是由另一个金额加上一个已有的硬币面值来的。
    可以得出:
    f(amount) = min(f(amount-coins[0]),f(amount-coins[1])…)+1

代码

  1. 解题思路是从上向下,但是按照这个思路写代码时,会比较麻烦。可以考虑自下而上的方式。
  2. 初始化数组dp[amount+1],下标表示金额,值为最少硬币数。
    dp[coins[0]]=dp[coins[i]]=…=1
  3. 由初始化后的数组,可推出之后所有的金额的最少硬币数。
    dp[i+coins[n]] = dp[i+coins[n]]>dp[i]+1?dp[i]+1:dp[i+coins[n]];
    public static int solution(int[] coins,int amount){

        int flag[] = new int[amount+1];

        if (amount == 0)
            return 0;
        for (int j = 0;j<=amount;j++){
            for (int i = 0;i<coins.length;i++){
                if (coins[i]>amount)
                    continue;
                if (j+coins[i] <= amount)
                    if ((flag[j]!=0||j == 0)&&(flag[j+coins[i]]>flag[j]+1||flag[j+coins[i]]==0))
                       flag[j+coins[i]] = flag[j]+1;
            }
        }
        return flag[amount]==0?-1:flag[amount];
    }
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值