Coin Change Minimum Coins in DSA C++ - Time & Space Complexity
We want to understand how the time needed to find the minimum coins changes as the amount grows.
How does the work increase when we try to make bigger amounts with given coins?
Analyze the time complexity of the following code snippet.
int minCoins(vector<int>& coins, int amount) {
vector<int> dp(amount + 1, amount + 1);
dp[0] = 0;
for (int i = 1; i <= amount; i++) {
for (int c : coins) {
if (c <= i) {
dp[i] = min(dp[i], dp[i - c] + 1);
}
}
}
return dp[amount] > amount ? -1 : dp[amount];
}
This code finds the minimum number of coins needed to make a given amount using dynamic programming.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Nested loops: outer loop runs for each amount from 1 to amount, inner loop runs for each coin.
- How many times: Outer loop runs amount times, inner loop runs coins.size() times for each outer iteration.
As the amount grows, the code checks each coin for every smaller amount up to the target.
| Input Size (amount) | Approx. Operations |
|---|---|
| 10 | 10 x number_of_coins |
| 100 | 100 x number_of_coins |
| 1000 | 1000 x number_of_coins |
Pattern observation: The operations grow linearly with the amount and the number of coins.
Time Complexity: O(amount x number_of_coins)
This means the time needed grows proportionally with the amount and how many coin types we have.
[X] Wrong: "The time depends only on the amount, not the number of coins."
[OK] Correct: Each coin is checked for every amount, so more coins mean more work.
Understanding this helps you explain how dynamic programming improves efficiency over simple recursion.
It shows you can analyze nested loops and relate them to input sizes clearly.
"What if we used recursion with memoization instead of this bottom-up approach? How would the time complexity change?"
Practice
Solution
Step 1: Understand the problem goal
The problem asks for the minimum number of coins needed to make a specific amount using given coin denominations.Step 2: Identify the correct description
The fewest number of coins needed to make a given amount correctly describes this goal, while others describe unrelated concepts.Final Answer:
The fewest number of coins needed to make a given amount -> Option AQuick Check:
Minimum coins = fewest coins needed [OK]
- Confusing minimum coins with total coin types
- Thinking about maximum amount instead of minimum coins
- Mixing sum of coins with count of coins
dp of size amount+1 initialized with INT_MAX?Solution
Step 1: Check vector declaration syntax
Correct syntax uses std::vector<int> dp(size, initial_value); std::vector<int> dp(amount+1, INT_MAX); matches this exactly.Step 2: Identify errors in other options
vector<int> dp(amount, 0); initializes with 0 and wrong size; std::vector dp(amount+1, INT_MAX); misses template brackets; vector<int> dp = new vector(amount+1, INT_MAX); uses incorrect new syntax.Final Answer:
std::vector<int> dp(amount+1, INT_MAX); -> Option CQuick Check:
Correct vector declaration = std::vector<int> dp(amount+1, INT_MAX); [OK]
- Omitting template brackets <>
- Using wrong initialization syntax
- Confusing size and initial value parameters
int coins[] = {1, 2, 5};
int amount = 11;
std::vector<int> dp(amount+1, INT_MAX);
dp[0] = 0;
for (int i = 1; i <= amount; i++) {
for (int c : coins) {
if (i - c >= 0 && dp[i - c] != INT_MAX) {
dp[i] = std::min(dp[i], dp[i - c] + 1);
}
}
}
std::cout << dp[amount] << std::endl;Solution
Step 1: Understand the DP approach
The code finds minimum coins to make amount 11 using coins {1,2,5} by building dp array.Step 2: Calculate minimum coins for 11
11 = 5 + 5 + 1 uses 3 coins, which is minimum. dp[11] = 3.Final Answer:
3 -> Option BQuick Check:
Minimum coins for 11 = 3 [OK]
- Assuming dp[amount] remains INT_MAX
- Counting total coin value instead of count
- Ignoring dp initialization and updates
int coins[] = {1, 3, 4};
int amount = 6;
std::vector<int> dp(amount+1, INT_MAX);
dp[0] = 0;
for (int i = 1; i <= amount; i++) {
for (int c : coins) {
if (i - c >= 0) {
dp[i] = std::min(dp[i], dp[i - c] + 1);
}
}
}
std::cout << dp[amount] << std::endl;Solution
Step 1: Analyze dp update condition
The code updates dp[i] without checking if dp[i - c] is INT_MAX, which can cause overflow.Step 2: Identify missing condition
Must check dp[i - c] != INT_MAX before adding 1 to avoid invalid calculations.Final Answer:
Missing check if dp[i - c] is INT_MAX before adding 1 -> Option DQuick Check:
Check dp[i - c] != INT_MAX before update [OK]
- Skipping dp[i-c] validity check
- Incorrect dp vector size
- Wrong initialization of dp[0]
{2, 5, 10} and amount 7, what is the minimum number of coins needed? If it is not possible, return -1.Solution
Step 1: Check possible combinations for amount 7
Coins are 2, 5, 10. 10 > 7 so ignore. Try 5 + 2 = 7 (2 coins). But 5 + 2 is valid, so minimum coins = 2.Step 2: Verify if 5 + 2 is allowed
Since 5 and 2 are in denominations, 7 can be made with 2 coins.Final Answer:
2 -> Option AQuick Check:
7 = 5 + 2 uses 2 coins [OK]
- Assuming no solution because 7 is odd
- Ignoring valid combinations with smaller coins
- Returning -1 incorrectly
Ready to prove it?
Pass the test and this pattern moves unknown
