思路分析:
- 创建一个动态规划数组
dp
,其中dp[i]
表示组成金额i
的最少硬币数量。 - 初始化
dp[0]
为 0,表示组成金额 0 的最少硬币数量为 0。 - 遍历硬币数组,对于每个硬币面值,从该面值开始更新
dp
数组。 - 如果使用当前硬币后,组成金额
j
的方式数量不是INT_MAX
(即可达到),则更新dp[j]
,表示组成金额j
的最少硬币数量为原先的数量和使用当前硬币的数量的较小值。 - 最终,如果组成目标金额的方式数量仍为
INT_MAX
,则表示无法组成该金额,返回 -1;否则返回组成目标金额的最少硬币数量。
class Solution {
public:
int coinChange(vector<int>& coins, int amount) {
// 创建一个动态规划数组 dp,其中 dp[i] 表示组成金额 i 的最少硬币数量
vector<int> dp(amount + 1, INT_MAX);
// 初始化 dp[0] 为 0,表示组成金额 0 的最少硬币数量为 0
dp[0] = 0;
// 遍历硬币数组
for (int i = 0; i < coins.size(); i++) {
// 从当前硬币面值开始更新 dp 数组
for (int j = coins[i]; j <= amount; j++) {
// 如果使用当前硬币 coins[i] 后,组成金额 j 的方式数量不是 INT_MAX(即可达到)
if (dp[j - coins[i]] != INT_MAX) {
// 更新 dp[j],表示组成金额 j 的最少硬币数量为原先的数量和使用当前硬币的数量的较小值
dp[j] = min(dp[j], dp[j - coins[i]] + 1);
}
}
}
// 如果组成目标金额的方式数量仍为 INT_MAX,则表示无法组成该金额,返回 -1
// 否则返回组成目标金额的最少硬币数量
if (dp[amount] == INT_MAX)
return -1;
else
return dp[amount];
}
};