一、322.零钱兑换
1.题目描述
给你一个整数数组 coins ,表示不同面额的硬币;以及一个整数 amount,表示总金额。计算并返回可以凑成总金额所需的 最少的硬币个数。如果没有任何一种硬币组合能组成总金额,返回 -1
你可以认为每种硬币的数量是无限的。
2.代码
3.思路
首先,创建一个长度为 amount + 1
的数组 dp
,并将数组元素初始化为 Integer.MAX_VALUE
,dp[j]
代表凑出金额 j
所需的最少硬币数量,同时将 dp[0]
初始化为 0,因为凑出金额 0 不需要任何硬币。
接着,通过两层循环填充 dp
数组。外层循环遍历硬币数组 coins
中的每个硬币面额;内层循环采用正序遍历,从当前硬币面额开始到目标金额 amount
,这是因为本题是完全背包问题,每个硬币可以使用多次。对于内层循环中的每个金额 j
,先检查 dp[j - coins[i]]
是否为初始最大值,若不是,则说明可以通过使用当前硬币 coins[i]
来更新 dp[j]
,此时取 dp[j]
和 dp[j - coins[i]] + 1
中的较小值作为新的 dp[j]
,这里的 +1
表示使用了当前这一枚硬币。
最后,若 dp[amount]
仍为初始最大值,说明无法凑出目标金额,返回 -1;否则返回 dp[amount]
,即凑出目标金额所需的最少硬币数量。
二、279.完全平方数
1.题目描述
给你一个整数 n,返回 和为n的完全平方数的最少数量
完全平方数 是一个整数,其值等于另一个整数的平方;换句话说,其值等于一个整数自乘的积。例如,1、4、9和 16 都是完全平方数,而 3 和 11 不是。
2.代码
3.思路
首先创建长度为 n + 1
的数组 dp
并初始化为 Integer.MAX_VALUE
,令 dp[0]
为 0,表示和为 0 时无需完全平方数。接着通过两层循环,外层遍历所有不超过 n
的完全平方数作为 “物品”,内层从当前完全平方数开始遍历到 n
作为 “背包”,对于每个和值 j
,若 dp[j - 当前完全平方数]
非初始最大值,则更新 dp[j]
为其自身与 dp[j - 当前完全平方数] + 1
中的较小值,最终返回 dp[n]
作为最少完全平方数数量。