版权声明:本文为博主原创文章,欢迎转载!转载请保留原博客地址。 https://blog.csdn.net/grllery/article/details/88535210
322. Coin Change
You are given coins of different denominations and a total amount of money amount. Write a function to compute the fewest number of coins that you need to make up that amount. If that amount of money cannot be made up by any combination of the coins, return -1.
Example 1:
Input: coins = [1, 2, 5], amount = 11
Output: 3
Explanation: 11 = 5 + 5 + 1
Example 2:
Input: coins = [2], amount = 3
Output: -1
Note:
You may assume that you have an infinite number of each kind of coin.
题目:通过组合给定面额的coins
,确定最少数量的coin
,使得其和为amount
,如果无法组成amount
,返回-1。每种面额的硬币个数不限。
思路1:回溯[Time Limit Exceeded]。遍历所有可能的情况,找出满足条件的所需的最少硬币个数。
class Solution {
public:
int coinChange(vector<int>& coins, int amount) {
vector<int> p;
int res = INT_MAX;
backtracking(coins, p, 0, amount, res);
return res == INT_MAX ? -1 : res;
}
private:
void backtracking(vector<int>& coins, vector<int>& p, int start, int remain, int& res){
if(remain < 0)
return;
else if(remain == 0){
res = min(res, (int)p.size());
return;
}
for(int i = start; i < coins.size(); ++i){
p.push_back(coins[i]);
backtracking(coins, p, i, remain - coins[i], res);
p.pop_back();
}
}
};
思路2:动态规划,参见解析。维护一个数组dp
,dp[i]
表示组成和为i
所需的最少的硬币个数,外层循环i
从1
到amount
,内层循环更新不同coin
对dp
的影响,判断是否能够通过coin
对dp[i]
进行松弛。注意dp[i]
初始化为amount+1
。
class Solution {
public:
int coinChange(vector<int>& coins, int amount) {
//注意,dp的初值不要设置为INT_MAX, 因为这样会导致dp[i - coins[j]] + 1可能变成负数
vector<int> dp(amount+1, amount+1);
dp[0] = 0;
//计算amount_ = 1,2,3....amount时所需的最少的coins的个数
for(int i = 1; i <= amount; ++i){
for(auto coin : coins){
if(i >= coin)
dp[i] = min(dp[i-coin] + 1, dp[i]);
}
}
return dp[amount] > amount ? -1 : dp[amount];
}
};