【代码随想录】零钱兑换

题目描述

image

分析

这道题分析起来并不难。递推公式也能分析出来,但是我当时写的时候疑惑的一个问题就是:如何判断硬币组合的总额刚好等于需要的金额,因为这里的dp数组很明显是组成总金额所需的最少硬币个数。
我试着加了一个数组存储当前情况下的金额。但是想一下就知道这样太笨了。实现起来也特别困难。
首先看一下代码随想录的代码:

class Solution {
public:
    int coinChange(vector<int>& coins, int amount) {
        vector<int> dp(amount + 1, INT_MAX);
        dp[0] = 0;
        for (int i = 0; i < coins.size(); i++) { // 遍历物品
            for (int j = coins[i]; j <= amount; j++) { // 遍历背包
                if (dp[j - coins[i]] != INT_MAX) { // 如果dp[j - coins[i]]是初始值则跳过
                    dp[j] = min(dp[j - coins[i]] + 1, dp[j]);
                }
            }
        }
        if (dp[amount] == INT_MAX) return -1;
        return dp[amount];
    }
};

它通过把dp数组的初始值设置为INT_MAX,并在遍历中设置条件if (dp[j - coins[i]] != INT_MAX)。
dp[0]设置为0是因为从0开始组合,也就是j == coins[i]的话,肯定能形成一种组合,而如果dp[j - coins[i]]为INT_MAX的话,就说明这个位置没有被修改过,也就是说没有一种组合的总金额刚好等于j,通过这种机制就能判断出组合总额凑不齐总金额的情况。
在最后返回的时候也能看出来,如果do[amount]为INT_MAX的话,就返回-1,代表没有组合的总额能等于amount

posted @ 2024-03-23 10:16  SaTsuki26681534  阅读(1)  评论(0编辑  收藏  举报