题目来源
322. 零钱兑换 - 力扣(LeetCode)

题目描述

给你一个整数数组 coins ,表示不同面额的硬币;以及一个整数 amount ,表示总金额。
计算并返回可以凑成总金额所需的 最少的硬币个数 。如果没有任何一种硬币组合能组成总金额,返回 -1 。
你可以认为每种硬币的数量是无限的。

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

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

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

分析

硬币不是排序好的,所以要先处理下数组。然后 amount=0,直接输出 0. 所以将 dp[0]写进 0 即可然后从小到大,找出每个金额 i 的最优解,最后就找到 amount 的最优解了。
重点理解
dp 动态规划的思想。要一步步的从小问题开始,例如本题,就是从金额 1 开始寻找最优解,直到找到 amount 的最优解

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
class Solution {
public int coinChange(int[] coins, int amount) {
// 先排序,样例有无序的
Arrays.sort(coins);
// 初始化一个较大的值,表示当前还未找到可行解
int[] dp = new int[amount + 1];
Arrays.fill(dp, amount + 1);
// 金额为0时,所需硬币个数为0,这是基础情况
dp[0] = 0;

// 从金额1块钱开始,凑i块钱需要多少个硬币
for (int i = 1; i <= amount; i++) {
for (int coin : coins) {
if (coin <= i) {
// dp[i]存的是金额为i的时候最少的硬币数量
// 尝试用当前硬币去凑金额i,取较小值(当前的dp[i]和使用该硬币后的情况对比)
// 比如i=7,coin =5,就表示现在七块钱,用五块钱硬币凑,如果花的硬币更少
// 就记录此时需要的最少金币数
dp[i] = Math.min(dp[i], dp[i - coin] + 1);
} else {
// 如果当前硬币面额大于要凑的金额,就不用继续尝试更大面额的硬币了
break;
}
}
}

// 如果最终结果还是初始化的较大值,说明无法凑出给定金额,返回 -1
return dp[amount] > amount? -1 : dp[amount];
}
}

Powered by: 🪐 Hexo + Stellar

本”页面“访问 次 | 👀总访问 次 | 总访客