C++ 0322.cpp
class Solution {
public:
int coinChange(vector<int>& coins, int amount) {
vector<int64_t> dp(11000, -1);
dp[0] = 0;
for (int64_t i = 0; i <= amount; i++)
{
if (dp[i] == -1)
continue;
for (auto c : coins)
{
int64_t sum = i + c;
if (sum > amount)
continue;
if (dp[sum] == -1)
dp[sum] = dp[i] + 1;
else
dp[sum] = min(dp[sum], dp[i] + 1);
}
}
return dp[amount];
}
};
Difficulty
and has an acceptance rate of about 49% (6+ million submissions).
Typical patterns to solve this problem:
- Array
- Breadth First Search
- Dynamic Programming
AI Disclaimer
However, two years later I set up this website and used various AI tools to generate most of the walkthrough / explanations below.
See this dedicated page for more details.
Code Walkthrough
Overview
The provided implementation solves the classic minimum-coin change problem using a bottom-up dynamic programming approach. It builds a one-dimensional table that records the smallest number of coins required to reach each intermediate amount up to the target. The algorithm iterates over reachable amounts and attempts to extend them with each coin denomination, updating the table whenever a better (smaller) count is found. The final answer is read directly from the table entry corresponding to the requested amount.
Key Steps
The initialization creates a DP vector sized for the maximum supported amount and marks all entries as unreachable with -1. The base case for amount zero is explicitly set to zero, establishing the starting point for the recurrence.
vector<int64_t> dp(11000, -1);
dp[0] = 0;
The outer loop walks through every amount from zero up to the target. A guard skips any amount that has not been reached yet, ensuring that only viable states participate in further expansion.
for (int64_t i = 0; i <= amount; i++)
{
if (dp[i] == -1)
continue;
// inner loop follows
}
Inside the outer loop, the inner loop iterates over each coin value. For each coin, it computes the prospective new sum and discards it if it would exceed the target amount. This prevents out-of-bounds accesses and unnecessary work.
for (auto c : coins)
{
int64_t sum = i + c;
if (sum > amount)
continue;
// update logic follows
}
When a valid new sum is found, the algorithm updates the DP entry. If the entry has never been set (-1), it adopts the count from the current state plus one coin. If the entry already holds a value, the algorithm retains the smaller of the existing count and the newly computed count, guaranteeing that the table always reflects the minimal number of coins discovered so far.
if (dp[sum] == -1)
dp[sum] = dp[i] + 1;
else
dp[sum] = min(dp[sum], dp[i] + 1);
Finally, the function returns the DP entry for the requested amount. If the amount is unreachable, the sentinel -1 propagates to the caller, indicating failure.
return dp[amount];
Edge Cases Handled
When the target amount is zero, the DP table entry dp[0] is preset to zero, causing the outer loop to immediately satisfy the condition and return the correct result without further processing.
If a particular coin value is larger than the remaining amount needed, the inner loop’s sum > amount check discards that transition, preventing invalid updates.
Unreachable amounts remain marked with -1 throughout the computation. The final return statement therefore conveys impossibility directly, without requiring additional post-processing.
The use of 64-bit integers for indices and DP values safeguards against overflow when the sum of an intermediate amount and a coin could exceed the range of a 32-bit integer, especially when large coin denominations are present.
Performance Optimizations
The algorithm avoids unnecessary work by skipping DP entries that are still -1. This early-continue pattern reduces the number of inner-loop executions dramatically when many amounts are unreachable early in the process.
By preallocating the DP vector to a fixed size (11000) and initializing it once, the code eliminates repeated memory allocations that would occur with dynamic resizing.
The conditional update distinguishes between first-time assignments and subsequent improvements, allowing the min operation to be invoked only when needed. This selective comparison reduces the total number of arithmetic operations.
Using a single linear DP array rather than a two-dimensional structure keeps the memory footprint compact and improves cache locality, leading to faster access patterns during the nested loops.
Overall, the combination of early pruning, preallocation, and minimal arithmetic yields an implementation that scales efficiently with the size of the input coin set and the target amount.
ELI5 - Simplified Explanation
Imagine you have a big pile of coins and you want to reach a specific total amount of money. This code is like a little robot helper that figures out the smallest number of coins needed to reach that exact total.
First, the robot sets up a long piece of paper with many boxes, and it labels each box with a number starting from zero up to the amount you want to reach. The robot writes a special mark in these boxes to show that it has not visited them yet. Then, the robot starts at the very first box, which represents zero, and says it takes zero coins to have zero money.
The robot looks at every box one by one. If a box has a mark showing the robot has not been there, it skips that box and moves to the next. If the robot has been to the box, it picks up every type of coin you have. For each coin, it adds the value of that coin to the current amount of money. This gives the robot a new total.
If this new total is not more than the final amount the robot is trying to reach, it checks to see if it found a way to get there already. If the robot has not found a way, it remembers how many coins it took to get to that new total. If it has been there before, it compares the number of coins it used now with the number it used before to keep only the smallest count. After checking every single box and every single coin, the robot knows the fewest number of coins needed to reach your total.
Code Quality
Complexity Analysis
Other Solutions
Obviously, I did that after I solved the problem myself.
In general, AlgoMonster and WalkCCC solutions are high-quality and always worth a look.
I haven't checked most of the other solutions, but they might be helpful as well.
And of course, the LeetCode forum is always a good place (or even the best) to look for alternative approaches.
(click on a column header to sort the table)
| author | |||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
| author | solutions | ||||||||||
| www | AlgoMonster | C++ | Python | Java | TS | ||||||
| WalkCCC | C++ | Python | Java | ||||||||
| leetcode.ca | C++ | Python | Java | JS | Rust | Go | TS | ||||
| LeetcodeHelp | C++ | Python | Java | ||||||||
| MemoryLimitExceeded | C++ | Python | |||||||||
| Progiez | C++ | Python | Java | ||||||||
| github | begeekmyfriend | C | |||||||||
| BigEggStudy | C# | ||||||||||
| black-shadows | C++ | ||||||||||
| bujosa | Python | ||||||||||
| chandansgowda | Python | ||||||||||
| charles-wangkai | Java | ||||||||||
| chenyanzhe | C++ | ||||||||||
| everthis | JS | ||||||||||
| FelixFan1122 | C# | ||||||||||
| fpdjsns | C++ | ||||||||||
| fsq | Python | ||||||||||
| Garvit244 | Python | ||||||||||
| gouthampradhan | Java | ||||||||||
| halfrost | Go | ||||||||||
| haoel | C++ | ||||||||||
| JoshCrozier | JS | ||||||||||
| keineahnung2345 | C++ | ||||||||||
| linouk23 | C++ | ||||||||||
| lkwq007 | Python | ||||||||||
| MacJim | C++ | ||||||||||
| qiyuangong | Python | ||||||||||
| ruoru | Rust | ||||||||||
| shreymehul | C# | ||||||||||
| sonugiri1043 | C++ | ||||||||||
| suxrobGM | C# | ||||||||||
| trung-hn | Python | ||||||||||
| varunu28 | Java | ||||||||||
| vli02 | C | ||||||||||
| vthwang | Java | ||||||||||
| wisdompeak | C++ | ||||||||||
| XiaotaoGuo | C++ | ||||||||||
| yuanliu666 | Kotlin | ||||||||||
| zfang399 | C++ | ||||||||||
| AlgoMonster | C++, Python, Java, TypeScript | ||||||||||
| WalkCCC | C++, Python, Java | ||||||||||
| leetcode.ca | C++, Go, Java, JavaScript, Python, Rust, TypeScript | ||||||||||
| LeetcodeHelp | C++, Java, Python | ||||||||||
| MemoryLimitExceeded | Python, C++ | ||||||||||
| Progiez | C++, Java, Python | ||||||||||
| begeekmyfriend | C | ||||||||||
| BigEggStudy | C# | ||||||||||
| black-shadows | C++, C++ | ||||||||||
| bujosa | Python | ||||||||||
| chandansgowda | Python | ||||||||||
| charles-wangkai | Java | ||||||||||
| chenyanzhe | C++ | ||||||||||
| everthis | JavaScript | ||||||||||
| FelixFan1122 | C# | ||||||||||
| fpdjsns | C++ | ||||||||||
| fsq | Python | ||||||||||
| Garvit244 | Python | ||||||||||
| gouthampradhan | Java | ||||||||||
| halfrost | Go | ||||||||||
| haoel | C++ | ||||||||||
| JoshCrozier | JavaScript | ||||||||||
| keineahnung2345 | C++ | ||||||||||
| linouk23 | C++ | ||||||||||
| lkwq007 | Python | ||||||||||
| MacJim | C++ | ||||||||||
| qiyuangong | Python | ||||||||||
| ruoru | Rust | ||||||||||
| shreymehul | C# | ||||||||||
| sonugiri1043 | C++ | ||||||||||
| suxrobGM | C# | ||||||||||
| trung-hn | Python | ||||||||||
| varunu28 | Java | ||||||||||
| vli02 | C | ||||||||||
| vthwang | Java | ||||||||||
| wisdompeak | C++ | ||||||||||
| XiaotaoGuo | C++ | ||||||||||
| yuanliu666 | Kotlin | ||||||||||
| zfang399 | C++ |
Videos
Similar Problems
- problem 983: Minimum Cost For Tickets
- problem 2224: Minimum Number of Operations to Convert Time
- problem 2952: Minimum Number of Coins to be Added
Solved On The Same Day
- problem 1: Two Sum
- problem 9: Palindrome Number
- problem 14: Longest Common Prefix
- problem 20: Valid Parentheses
- problem 26: Remove Duplicates from Sorted Array
- problem 27: Remove Element
- problem 83: Remove Duplicates from Sorted List
- problem 88: Merge Sorted Array
- problem 94: Binary Tree Inorder Traversal
- problem 100: Same Tree
- problem 104: Maximum Depth of Binary Tree
- problem 121: Best Time to Buy and Sell Stock
- problem 136: Single Number
- problem 141: Linked List Cycle
- problem 169: Majority Element
- problem 190: Reverse Bits
- problem 226: Invert Binary Tree
- problem 234: Palindrome Linked List
- problem 1114: Print in Order
- problem 3: Longest Substring Without Repeating Characters
- problem 7: Reverse Integer
- problem 8: String to Integer (atoi)
- problem 11: Container With Most Water
- problem 12: Integer to Roman
- problem 15: 3Sum
- problem 17: Letter Combinations of a Phone Number
- problem 22: Generate Parentheses
- problem 31: Next Permutation
- problem 36: Valid Sudoku
- problem 39: Combination Sum
- problem 40: Combination Sum II
- problem 45: Jump Game II
- problem 46: Permutations
- problem 47: Permutations II
- problem 48: Rotate Image
- problem 49: Group Anagrams
- problem 55: Jump Game
- problem 59: Spiral Matrix II
- problem 75: Sort Colors
- problem 77: Combinations
- problem 91: Decode Ways
- problem 95: Unique Binary Search Trees II
- problem 96: Unique Binary Search Trees
- problem 134: Gas Station
- problem 164: Maximum Gap
- problem 189: Rotate Array
- problem 215: Kth Largest Element in an Array
- problem 238: Product of Array Except Self
- problem 287: Find the Duplicate Number
- problem 347: Top K Frequent Elements
- problem 377: Combination Sum IV
- problem 438: Find All Anagrams in a String
- problem 474: Ones and Zeroes
- problem 518: Coin Change II
- problem 526: Beautiful Arrangement
- problem 763: Partition Labels
- problem 983: Minimum Cost For Tickets
- problem 994: Rotting Oranges
- problem 1027: Longest Arithmetic Subsequence
- problem 2140: Solving Questions With Brainpower
- problem 2466: Count Ways To Build Good Strings
- problem 4: Median of Two Sorted Arrays
- problem 41: First Missing Positive
Extra
- Tech Stack - my development environment and tools
- AI - how AI helped me create this website (NOT solving the problems)
- Progress - progression over time
- Quality - code quality