- Coin Change
Medium
17.4K
391
Companies
You are given an integer array coins representing coins of different denominations and an integer amount representing a total amount of money.
Return 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.
You may assume that you have an infinite number of each kind of coin.
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
Example 3:
Input: coins = [1], amount = 0
Output: 0
Constraints:
1 <= coins.length <= 12
1 <= coins[i] <= 231 - 1
0 <= amount <= 104
解法1:动态规划。注意此题不可用贪婪法。比如coins = {1, 3, 4}, amount = 6. 用贪婪法得到{4, 1, 1}这种组合,但实际上最优解是{3,3}。
class Solution {
public:
int coinChange(vector<int>& coins, int amount) {
int n = coins.size();
if (n == 0 || amount == 0) return 0;
vector<int> dp(amount + 1, INT_MAX);
for (int i = 1; i <= amount; i++) {
for (auto j : coins) {
if (i == j) dp[i] = 1;
else if (i > j && dp[i - j] != INT_MAX) {
dp[i] = min(dp[i], dp[i - j] + 1);
}
}
}
if (dp[amount] == INT_MAX) return -1;
return dp[amount];
}
};
二刷:
class Solution {
public:
int coinChange(vector<int>& coins, int amount) {
int n = coins.size();
if (n == 0 || amount == 0) return 0;
vector<int> dp(amount + 1, amount + 1);
dp[0] = 0;
for (int i = 1; i <= amount; i++) {
for (int coin : coins) {
if (i >= coin)
dp[i] = min(dp[i], dp[i - coin] + 1);
}
}
return dp[amount] == amount + 1 ? -1 : dp[amount];
}
};
解法2:回溯
class Solution {
public:
int coinChange(vector<int>& coins, int amount) {
vector<int> memos(amount + 1, -INT_MAX/3);
return helper(coins, amount, memos);
}
private:
int helper(vector<int>& coins, int amount, vector<int> &memos) {
if (amount == 0) return 0;
if (memos[amount] != -INT_MAX/3) return memos[amount];
int res = INT_MAX;
for (int coin : coins) {
if (amount >= coin) {
int result = helper(coins, amount - coin, memos);
if (result < 0) continue;
else res = min(res, result);
}
}
if (res < 0 || res == INT_MAX) memos[amount] = -1;
else memos[amount] = res + 1;
return memos[amount];
}
vector<int> mems;
};
文章介绍了如何使用动态规划和回溯算法解决最少硬币组合问题,给出了一种在给定不同面额硬币数组和总金额的情况下,找到组成该金额所需的最少硬币数量的方法。如果无法组成,返回-1。
991

被折叠的 条评论
为什么被折叠?



