【LeetCode刷题(中等程度)】322. 零钱兑换

给定不同面额的硬币 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
示例 4:

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

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

提示:

1 <= coins.length <= 12
1 <= coins[i] <= 231 - 1
0 <= amount <= 231 - 1

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/coin-change
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路:本题是动态规划题,我们假设:f(X) = 最少用多少枚硬币拼出X,因为如果能拼出的话,最后一枚硬币肯定是从coins中的一个,所以转移方程为:
f[i] = min(f[i-coins[0]]+1,...,f[i-coins[n-1]]+1)
而边界条件为:f(0) = 0
时间复杂度:O(amount*n) n为硬币种数

在这里插入图片描述

class Solution {
public:
    int coinChange(vector<int>& coins, int amount) {
        vector<int> f(amount + 1,0);

        int n = coins.size();//硬币的种数

        for(int  i = 1;i <= amount;++i)//拼amount钱数 总共需要迭代amount步
        {
            f[i] = INT_MAX; //最初设定为无穷大

            //下面枚举的就是最后一步
            // f[i] = min(f[i-coins[0]]+1,...,f[i-coins[n-1]]+1)
            for(int j = 0;j < n;++j)
            {
                //1 是确保我们要拼的钱数大于当前选的硬币
                //2 是确保编程中INT_MAX不越界
                if(i>=coins[j] && f[i-coins[j]] != INT_MAX) 
                    f[i]  = min(f[i - coins[j]]+1,f[i]);
            }
        }
        if(f[amount] == INT_MAX)
            return -1;
        return f[amount];
    }
};

猜你喜欢

转载自blog.csdn.net/qq_33197518/article/details/108890219
今日推荐