322. 零钱兑换(动态规划)

/**
 * 322. 零钱兑换
 * @author wsq
 * @date 2020/10/13
	给定不同面额的硬币 coins 和一个总金额 amount。编写一个函数来计算可以凑成总金额所需的最少的硬币个数。如果没有任何一种硬币组合能组成总金额,返回 -1。
	你可以认为每种硬币的数量是无限的。
	
	示例 1:
	输入:coins = [1, 2, 5], amount = 11
	输出:3 
	解释:11 = 5 + 5 + 1

	示例 2:
	输入:coins = [2], amount = 3
	输出:-1
	
	链接:https://leetcode-cn.com/problems/coin-change
 */
package com.wsq.dp;

public class CoinChange {
	/**
	 *	动态规划
	 *	1.确定最后一步(金额amount兑换硬币的最少个数)
	 *	2.子问题:到达金额amount有几种情况,(比如:从金币额度2、5等到达amount)
	 *	3.定义转移方程, 比如f[i] = Math.min(f[i - 2], f[i - 5]) + 1
	 *	4.初始值以及边界情况
	 *	5.计算状态矩阵的顺序
	 * @param coins
	 * @param amount
	 * @return
	 */
	public int coinChange(int[] coins, int amount) {
		// 开数组,明确有多少中情况需要存储
        int[] dp = new int[amount + 1];
        // 获取硬币的种类数
        int n = coins.length;
        // 初始条件 金额为0时 兑换的硬币数为0
        dp[0] = 0;
        
        // 从小到大求出每一个状态的值
        for(int i = 1; i < amount + 1; i++){
        	// 由于是要求最小的 硬币兑换数, 因此在未求出之前, 每一个状态值都初始化为Integer.MAX_VALUE
            dp[i] = Integer.MAX_VALUE;
            for(int j = 0; j < n; j++){
                // 考虑dp[i - coins[j]] != Integer.MAX_VALUE是因为可能存在部分金额无法兑换成功
                if(i >= coins[j] && dp[i - coins[j]] != Integer.MAX_VALUE){
                    dp[i] = Math.min(1 + dp[i - coins[j]], dp[i]);
                }
            }
        }
        if(dp[amount] == Integer.MAX_VALUE){
            dp[amount] = -1;
        }
        return dp[amount];
    }
	
	
	public static void main(String[] args) {
		int[] coins = {1, 2, 5};
		int amount = 10;
		CoinChange cc = new CoinChange();
		int ans = cc.coinChange(coins, amount);
		System.out.println(ans);
	}
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值