第322题:零钱兑换

一. 问题描述

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

示例 1:

输入: coins = [1, 2, 5], amount = 11

输出: 3

解释: 11 = 5 + 5 + 1

示例 2:

输入: coins = [2], amount = 3

输出: -1

说明:

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

二. 解题思路

本题思路:本题采用动态规划的方式进行求解,考虑前n金额,所需要的银币最小数。找到转移方程f(n)=f(n-1)+coins。

步骤一:从题目中,我们可以想到如果从金额1开始,依次找到最小的硬币数,那么到了n元,也能找到其最小的硬币数。

步骤二:创建数组temp,其长度为n,代表前n元每一个的最小硬币数,并初始化为0.

步骤三:开始遍历一遍coins数组,temp[coins[i]]=1;

步骤四:开始遍历一遍temp数组j,并对每一个不为零的数组值遍历coins数组, temp[j+coins[i]]=min(temp[j]+1,temp[j+coins[i]]),注意当temp[j+coins[i]]==0时,直接添加temp[j+coins[i]]= temp[j]+1;

步骤五:直到所有遍历结束,输出最后一位的值,就是所求的值。

第一种:

三. 执行结果

执行用时 :13 ms, 在所有 java 提交中击败了71.21%的用户

内存消耗 :35.9 MB, 在所有 java 提交中击败了94.99%的用户

四. Java代码

class Solution {
    public int coinChange(int[] coins, int amount) {
        if(amount==0) {
            return 0;
        }
         int []temp=new int[amount];
    for(int i=0;i<coins.length;i++) {
        if(coins[i]<=temp.length)
        temp[coins[i]-1]=1;
    }
    int result=-1;
    for(int j=0;j<amount;j++) {
        if(temp[j]==0) {
            continue;
        }
        if(temp[amount-1]!=0) {
            if(result==-1) {
                result=temp[amount-1];
            }else if(result>temp[amount-1]) {
                result=temp[amount-1];
            }
        }
        for(int m=0;m<coins.length;m++) {
            if(coins[m]>=temp.length||j+coins[m]>=temp.length) {
                continue;
            }else if(temp[j+coins[m]]==0||temp[j+coins[m]]>temp[j]+1) {
                temp[j+coins[m]]=temp[j]+1;
            }
        }
        
    }
    return result;
    }
}
原文地址:https://www.cnblogs.com/xiaobaidashu/p/12123953.html