零钱兑换00

题目链接

零钱兑换

题目描述

零钱兑换00

注意

  • 至少有一种硬币
  • 最终返回的是总金额所需的最少硬币数
  • 可以认为每种硬币的数量是无限的
  • 1 <= coins[i] <= 231 - 1

解答思路

  • 采用动态规划从总金额为0开始推算出总金额为amount所需的最少硬币数

代码

public class Solution {
    public int coinChange(int[] coins, int amount) {
        // dp数组记录从0到amount金额所需的最少硬币个数,初始值设置为max
        int max = amount + 1;
        int[] dp = new int[max];
        Arrays.fill(dp, max);

        // 当总金额为0时,最少的硬币个数就是0
        dp[0] = 0;

        // 从金额1推算到金额amount所需的最少硬币个数
        for (int i = 1; i <= amount; i++) {
            // 遍历数组中的硬币面额
            for (int j = 0; j < coins.length; j++) {
                if (coins[j] <= i) {
                    // 金额i所需的最少硬币个数,只有在(i - coins[j] >= 0)时才进入判断
                    // 如果没有硬币金额可以组合成i - coins[j],则dp[i - coins[j]]的值大于amount,对后续结果没影响
                    dp[i] = Math.min(dp[i], dp[i - coins[j]] + 1);
                }
            }
        }

        return dp[amount] > amount ? -1 : dp[amount];
    }
}

关键点

  • 将dp数组的初始值设置为amount + 1,因为硬币的最小面额也是1,如果全是由1组成的总金额,所需要的最多硬币数也只有amount,在最终结果的判断中,如果dp[amount]的值大于amount,则说明没有任何一种硬币的组合可以达到总金额,此时应返回-1
  • 当总金额amount为0时,所需的最少硬币数也是唯一一种组合就是0个硬币
  • 对每个金额i,都要将i减去硬币数组中的所有面额后的dp值进行判断,找到其中的最小值,如果i减去某个硬币的面额后小于0,则说明该硬币无法组合成总金额,直接跳过不进行判断
上一篇:Loadrunner安装与破解【转】


下一篇:个人银行账户管理程序c++源码改java