虫虫首页| 资源下载| 资源专辑| 精品软件
登录| 注册

您现在的位置是:首页 > 技术阅读 >  每日一题:零钱兑换

每日一题:零钱兑换

时间:2024-02-14

给定不同面额的硬币 coins 和一个总金额 amount。编写一个函数来计算可以凑成总金额所需的最少的硬币个数。如果没有任何一种硬币组合能组成总金额,返回 -1。

示例1:

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

示例2:

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

说明:

你可以认为每种硬币的数量是无限的。

分析

这题可以用贪心也可以用dp,这里使用dp方式,以示例1举例,如下图


有硬币[1, 2, 5],想要组成11,那就需要先组成(11-1, 11-2, 11-5),即(10, 9, 6),括号内为或关系,就是说想要组成11,那就需要先组成10或9或6,这里用dp存储组成x需要的硬币个数,则dp[11]= min(dp[10], dp[9], dp[6])+1,依此类推,dp[10] = min(dp[10-1], dp[10-2], dp[10-5]) + 1,这是从上向下类推,基本上从上向下类推的规律都可以从下向上推导,具体可以看代码啦。

代码

class Solution {public:    int coinChange(vector<int>& coins, int amount) {        if (amount == 0) return 0;        // 如果没有任何一种硬币组合能组成总金额,返回 -1        const int fail_value = -1;        vector<int> dp(amount + 1, fail_value);        std::sort(coins.begin(), coins.end());        for (int i = 1; i <= amount; ++i) {            for (auto coin : coins) {                if (i == coin) {                    dp[i] = 1;                    break;                }                if (i < coin) {                    break;                }                if (dp[i-coin] != fail_value) {                    if (dp[i] == fail_value) {                        dp[i] = dp[i-coin] + 1;                    } else {                        dp[i] = min(dp[i-coin] + 1, dp[i]);                    }                }            }        }        return dp[amount];    }};

如有任何问题,可以联系喵大人 ,我会尽快回复哒!