The Coin Change Problem is a well-known algorithmic challenge that tests both your problem-solving skills and your understanding of dynamic programming. At first glance, it may seem simple, but the various strategies to solve it can lead to deeper insights into algorithm design. In this blog, we’ll go through the problem definition, multiple solving approaches, and practical coding examples.
The Coin Change Problem can be defined as follows:
Given a set of coin denominations and a target amount, the task is to determine the minimum number of coins needed to make that amount, or to find out if it’s impossible to achieve that quantity with the given coins.
Imagine you have coins of denominations [1, 2, 5], and you want to make the amount of 11. The most efficient way to do this would be:
This gives you a total of 5 coins (1 + 3 + 1 = 5), which is the minimum number needed.
However, if you change the target amount to 3 with the same denominations, you can achieve it using:
Conversely, if the target is 7, it is impossible to achieve that with these denominations.
Coins: [1, 2, 5]
Amount: 11
The goal is to find the optimal way to create these combinations.
The brute force approach explores every combination of coins that can sum to the target amount. This method has a time complexity of O(2^n) where n is the number of coins, making it impractical for larger inputs.
def coinChange(coins, amount): if amount == 0: return 0 if amount < 0: return float('inf') min_coins = float('inf') for coin in coins: res = coinChange(coins, amount - coin) min_coins = min(min_coins, res + 1) return min_coins result = coinChange([1, 2, 5], 11) print(result if result != float('inf') else -1) # Output: 3
Dynamic programming provides a more efficient way to solve this problem by storing intermediate results. We can build a table where each index represents a target amount, and the value at that index represents the minimum number of coins needed.
dp
of size amount + 1
with all values set to float('inf')
, except for dp[0]
which should be set to 0 (0 coins needed to make amount 0).amount
.dp[i]
to be the minimum between its current value and dp[i - coin] + 1
.def coinChange(coins, amount): dp = [float('inf')] * (amount + 1) dp[0] = 0 for coin in coins: for i in range(coin, amount + 1): dp[i] = min(dp[i], dp[i - coin] + 1) return dp[amount] if dp[amount] != float('inf') else -1 result = coinChange([1, 2, 5], 11) print(result) # Output: 3
A related problem is to determine the number of ways to make change for a given amount using the specified denominations. While the logic is similar, we’ll change our approach slightly to count valid combinations rather than minimize the number of coins.
def coinChangeII(coins, amount): dp = [0] * (amount + 1) dp[0] = 1 # There's one way to create amount 0: using 0 coins. for coin in coins: for i in range(coin, amount + 1): dp[i] += dp[i - coin] return dp[amount] result = coinChangeII([1, 2, 5], 5) print(result) # Output: 4 (combinations: 5, 2+2+1, 2+1+1+1, 1+1+1+1+1)
This implementation provides a clear way to determine the number of ways to achieve a target amount using the provided coins, showcasing the flexibility of dynamic programming.
Understanding the Coin Change Problem not only deepens your grasp of dynamic programming concepts but also prepares you for various algorithmic challenges during interviews. By exploring multiple approaches, you can develop a versatile skill set that can be adapted to similar problems in the future.
15/11/2024 | DSA
23/09/2024 | DSA
13/10/2024 | DSA
15/11/2024 | DSA
23/09/2024 | DSA
06/12/2024 | DSA
15/11/2024 | DSA
06/12/2024 | DSA
06/12/2024 | DSA
06/12/2024 | DSA
13/10/2024 | DSA