LeetCode link: 322. Coin Change
You are given an integer array
coins
representing coins of different denominations and an integeramount
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
------------------------------------------------------------------------
Constraints:
1 <= coins.length <= 12
1 <= coins[i] <= 2**31 - 1
0 <= amount <= 10000
It is a Unbounded Knapsack Problem
.
Detailed solutions will be given later, and now only the best practices in 7 languages are given.
- Time:
O(n * m)
. - Space:
O(n)
.
public class Solution
{
public int CoinChange(int[] coins, int amount)
{
int defaultValue = amount + 2; // As long as the value is greater than 'amount', it doesn't matter how much it is.
int[] dp = Enumerable.Repeat(defaultValue, amount + 1).ToArray();
dp[0] = 0;
for (var i = 1; i < dp.Length; i++)
{
foreach (int coin in coins)
{
if (i >= coin)
{
dp[i] = Math.Min(dp[i], dp[i - coin] + 1);
}
}
}
if (dp.Last() == defaultValue)
return -1;
return dp.Last();
}
}
class Solution:
def coinChange(self, coins: List[int], amount: int) -> int:
default_value = amount + 2 # As long as the value is greater than 'amount', it doesn't matter how much it is.
dp = [default_value] * (amount + 1)
dp[0] = 0
for i in range(1, len(dp)):
for coin in coins:
if i >= coin:
dp[i] = min(dp[i], dp[i - coin] + 1)
if dp[-1] == default_value:
return -1
return dp[-1]
class Solution {
public:
int coinChange(vector<int>& coins, int amount) {
auto default_value = amount + 2; // As long as the value is greater than 'amount', it doesn't matter how much it is.
auto dp = vector<int>(amount + 1, default_value);
dp[0] = 0;
for (auto i = 1; i < dp.size(); i++) {
for (auto coin : coins) {
if (i >= coin) {
dp[i] = min(dp[i], dp[i - coin] + 1);
}
}
}
if (dp.back() == default_value) {
return -1;
}
return dp.back();
}
};
class Solution {
public int coinChange(int[] coins, int amount) {
var defaultValue = amount + 2; // As long as the value is greater than 'amount', it doesn't matter how much it is.
var dp = new int[amount + 1];
Arrays.fill(dp, defaultValue);
dp[0] = 0;
for (var i = 1; i < dp.length; i++) {
for (var coin : coins) {
if (i >= coin) {
dp[i] = Math.min(dp[i], dp[i - coin] + 1);
}
}
}
var result = dp[dp.length - 1];
if (result == defaultValue) {
return -1;
}
return result;
}
}
var coinChange = function (coins, amount) {
const DEFAULT_VALUE = amount + 2 // As long as the value is greater than 'amount', it doesn't matter how much it is.
const dp = Array(amount + 1).fill(DEFAULT_VALUE)
dp[0] = 0
for (let i = 1; i < dp.length; i++) {
for (const coin of coins) {
if (i >= coin) {
dp[i] = Math.min(dp[i], dp[i - coin] + 1)
}
}
}
if (dp.at(-1) == DEFAULT_VALUE) {
return -1
}
return dp.at(-1)
};
func coinChange(coins []int, amount int) int {
defaultValue := amount + 2 // As long as the value is greater than 'amount', it doesn't matter how much it is.
dp := slices.Repeat([]int{defaultValue}, amount + 1)
dp[0] = 0
for i := 1; i < len(dp); i++ {
for _, coin := range coins {
if i >= coin {
dp[i] = min(dp[i], dp[i - coin] + 1)
}
}
}
result := dp[len(dp) - 1]
if result == defaultValue {
return -1
}
return result
}
def coin_change(coins, amount)
default_value = amount + 2 # As long as the value is greater than 'amount', it doesn't matter how much it is.
dp = Array.new(amount + 1, default_value)
dp[0] = 0
(1...dp.size).each do |i|
coins.each do |coin|
dp[i] = [ dp[i], dp[i - coin] + 1 ].min if i >= coin
end
end
return -1 if dp[-1] == default_value
dp[-1]
end
// Welcome to create a PR to complete the code of this language, thanks!
// Welcome to create a PR to complete the code of this language, thanks!