3116. Kth Smallest Amount With Single Denomination Combination
โ Runtime tested โ the solution passes every example case. ๐ Full written solution: https://interview-kit-fe.vercel.app/kth-smallest-amount-with-single-denomination-combination ๐ป Code on GitHub: https://github.com/timepasshub2539-hue/leetcode-python/tree/main/kth-smallest-amount-with-single-denomination-combination Chapters: 0:00 Amounts You Can't Pay 0:16 LeetCode 3116: Kth Smallest Amount 0:31 LeetCode 3116 0:44 Problem Statement 1:05 Worked Example 1:29 Constraints 1:47 Brute Force Approach 2:04 Merging Multiples Problem 2:18 Reframing The Problem 2:28 Inclusion-Exclusion Principle 2:54 Binary Search On Answer 3:10 Count Function Implementation 3:33 Binary Search Implementation 3:50 Full Solution Walkthrough 4:56 Why Binary Search Wins 5:10 Real-World Analogy 5:25 Time Complexity Analysis 5:49 Correctness Proof 6:12 Runtime Benchmark 6:27 Quick Quiz 6:39 Pause And Think 6:41 Quiz Answer 6:52 Round Two 7:04 Pause And Think 7:06 Quiz Answer 7:18 Kth Smallest Amount Recap โ Runtime tested โ the solution passes every example case. ๐ Full written solution: https://interview-kit-fe.vercel.app/kth-smallest-amount-with-single-denomination-combination ๐ป Code on GitHub: https://github.com/timepasshub2539-hue/leetcode-python/tree/main/kth-smallest-amount-with-single-denomination-combination Chapters: 0:00 Some Amounts You Can Never Pay 0:16 LeetCode 3116 Overview 0:31 LeetCode 3116 0:44 The Problem Statement 1:05 Worked Example 1:29 Constraints 1:47 Brute Force Approach 2:04 Merging Multiples Problem 2:18 Flipping The Question 2:28 Inclusion-Exclusion Counting 2:54 Binary Search On Answer 3:10 Count Function Code 3:33 Binary Search Code 3:50 Full Solution 5:01 Why It Beats Brute Force 5:14 Vending Machine Analogy 5:30 Time Complexity 5:54 Correctness Proof 6:16 Runtime Benchmark 6:32 Quick Quiz 6:44 Pause And Think 6:46 Quiz Answer 6:56 Round Two 7:09 Pause And Think 7:10 Quiz Answer 7:23 Kth Smallest Amount Recap โ Runtime tested โ the solution passes every example case. ๐ Full written solution: https://interview-kit-fe.vercel.app/kth-smallest-amount-with-single-denomination-combination ๐ป Code on GitHub: https://github.com/timepasshub2539-hue/leetcode-python/tree/main/kth-smallest-amount-with-single-denomination-combination Chapters: 0:00 Amounts You Can't Pay 0:16 LeetCode 3116: Kth Smallest Amount 0:31 LeetCode 3116 0:44 The Problem Statement 1:05 Worked Example 1:29 Constraints 1:47 First Approach: Brute Force 2:04 Merging Multiples Problem 2:18 Flipping The Question 2:28 Inclusion-Exclusion Counting 2:54 Binary Search On The Answer 3:10 Coding The Count Function 3:33 Coding The Binary Search 3:50 Full Solution Walkthrough 4:55 Time Complexity Advantage 5:08 Vending Machine Analogy 5:23 Time & Space Complexity 5:47 Correctness Proof 6:10 Benchmark Timing 6:26 Quick Quiz 6:38 Pause And Think 6:40 Quiz Answer 6:50 Round 2 Quiz 7:03 Pause And Think 7:04 Quiz Answer 7:17 Kth Smallest Amount Recap โ Runtime tested โ the solution passes every example case. ๐ Full written solution: https://interview-kit-fe.vercel.app/kth-smallest-amount-with-single-denomination-combination ๐ป Code on GitHub: https://github.com/timepasshub2539-hue/leetcode-python/tree/main/kth-smallest-amount-with-single-denomination-combination Chapters: 0:00 Amounts You Can't Pay 0:16 LeetCode 3116 0:31 LeetCode 3116 0:44 Problem Statement 1:05 Worked Example 1:29 Constraints 1:47 Brute Force Approach 2:04 Merging Multiples 2:18 Flipping The Question 2:28 Inclusion-Exclusion Counting 2:54 Binary Search Setup 3:10 Counting Function 3:33 Binary Search Function 3:50 Full Solution 4:54 Complexity Comparison 5:08 Vending Machine Example 5:23 Time Complexity 5:47 Correctness Proof 6:10 Runtime Benchmark 6:25 Quick Quiz 6:37 Pause And Think 6:40 Quiz Answer 6:50 Round Two 7:03 Pause And Think 7:04 Quiz Answer 7:16 Kth Smallest Amount โ Runtime tested โ the solution passes every example case. ๐ Full written solution: https://interview-kit-fe.vercel.app/kth-smallest-amount-with-single-denomination-combination ๐ป Code on GitHub: https://github.com/timepasshub2539-hue/leetcode-python/tree/main/kth-smallest-amount-with-single-denomination-combination Chapters: 0:00 Some Amounts You Can't Pay 0:16 LeetCode 3116 Overview 0:31 LeetCode 3116 0:44 Problem Statement 1:05 Worked Example 1:29 Constraints 1:47 Brute Force Approach 2:04 Merging Multiples Problem 2:18 Flipping The Question 2:28 Inclusion-Exclusion Counting 2:54 Binary Search Setup 3:10 Count Function Code 3:33 Binary Search Code 3:50 Full Solution 4:05 Why It Beats Brute Force 4:18 Vending Machine Analogy 4:34 Time Complexity 4:58 Correctness Proof 5:21 Benchmark Timing 5:36 Quiz Time 5:48 Pause And Think 5:50 Quiz Answer 6:00 Round Two 6:13 Pause And Think 6:14 Round Two Answer 6:27 Kth Smallest Amount Recap โ Runtime tested โ the solution passes every example case. ๐ Full written solution: https://interview-kit-fe.vercel.app/kth-smallest-amount-with-single-denomination-combination ๐ป Code on GitHub: https://github.com/timepasshub2539-hue/leetcode-python/tree/main/kth-smallest-amount-with-single-denomination-combination Chapters: 0:00 Unpayable Amounts 0:16 LeetCode 3116 Overview 0:31 LeetCode 3116 0:44 Problem Statement 1:05 Worked Example Walkthrough 1:29 Key Constraints 1:47 Brute Force Approach 2:04 Merging Multiples Problem 2:18 Reframing The Question 2:28 Inclusion-Exclusion Counting 2:54 Binary Search Setup 3:10 Counting Function Code 3:33 Binary Search Code 3:50 Full Solution Walkthrough 4:04 Complexity Comparison 4:18 Vending Machine Analogy 4:33 Time And Space Complexity 4:57 Correctness Proof 5:20 Runtime Benchmark 5:35 Quiz Time 5:47 Think It Through 5:49 Quiz Answer 6:00 Round Two Quiz 6:12 Think It Through 6:14 Quiz Answer 6:26 Kth Smallest Amount Recap โ Runtime tested โ the solution passes every example case. ๐ Full written solution: https://interview-kit-fe.vercel.app/kth-smallest-amount-with-single-denomination-combination ๐ป Code on GitHub: https://github.com/timepasshub2539-hue/leetcode-python/tree/main/kth-smallest-amount-with-single-denomination-combination Chapters: 0:00 Amounts You Can Never Pay 0:16 LeetCode 3116 Overview 0:31 LeetCode 3116 0:44 Problem Statement 1:05 Worked Example 1:29 Constraints 1:47 Naive Approach 2:04 Merging Multiples Problem 2:18 Flipping The Question 2:28 Inclusion-Exclusion Counting 2:54 Binary Search Setup 3:10 Count Function Code 3:33 Binary Search Code 3:50 Full Solution 4:04 Complexity Vs Brute Force 4:17 Vending Machine Analogy 4:33 Time Complexity 4:57 Correctness Proof 5:15 Runtime Benchmark 5:30 Quiz Time 5:43 Pause And Think 5:45 Quiz Answer 5:55 Round 2 Quiz 6:08 Pause And Think 6:09 Quiz Answer 6:22 Kth Smallest Amount Recap Some amounts just can't be paid with a fixed set of coin denominations โ LeetCode 3116 asks for the Kth smallest amount that CAN be paid using exactly one denomination at a time. We trace the real example, see why merging sorted multiples gets messy fast, then flip the question into counting multiples with inclusion-exclusion and binary search the answer instead. Full walkthrough: the count function, the search function, correctness proof, and a real timing comparison against brute force. #leetcode #python #binarysearch #codinginterview #dsa Watch next: - Maximum Subarray Sum With Length Divisible by K: https://youtu.be/2ehjpxdeFZI - SQL Lesson 26: Why Your View Recomputes Every Single Time: https://youtu.be/BVqaWW3STUw - The Problem: Longest Subsequence With Non-Zero Bitwise XOR #shorts: https://youtu.be/F9DwG4txKsU
Introduction
Some problems look like a data structures exercise until you actually try to run your solution at scale โ then they turn into a math problem in disguise. LeetCode 3116, Kth Smallest Amount With Single Denomination Combination, is exactly that kind of problem, and it's a favorite in hard-tier interview rounds because it tests something more valuable than syntax: can you recognize when brute force is structurally doomed, and can you reframe a problem you can't solve directly into one you can?
The setup sounds simple. You have a coin machine that only takes one denomination per payment โ no mixing 3s and 4s in the same transaction. Across every denomination, sorted from smallest to largest, you need the k-th amount that could ever be paid. It's a clean question with a nasty catch: k can be up to two billion, which immediately rules out any approach that tries to construct the answer directly.
Interviewers like this problem because it forces a mental shift that shows up constantly in real systems โ from rate limiters to search ranking to inventory queries. When you can't enumerate the answer space, you count instead, and you binary search on the count. Once you've internalized that pattern, a whole category of "find the k-th X" problems stops being intimidating.
Problem Overview
You're given an array of coin values, and you can use unlimited coins of any single denomination in one payment โ but you can never combine two different denominations. So if 3 is one of your coins, valid amounts are 3, 6, 9, 12, and so on. If 4 is also a coin, 4, 8, 12, 16 join the list too.
Now take every amount payable by any denomination, merge them all into one sorted list with duplicates removed, and return the k-th smallest value in that merged list.
Two constraints define the shape of the solution:
- The coin array has at most 15 elements, which matters because 2^15 is only about 32,000 โ small enough to iterate over every subset of coins.
- k can be as large as 2 billion, which rules out building any list of amounts, since that list would need to hold billions of entries before you could even sort it.
Example
Take coins [3, 6, 9] with k = 3.
- Multiples of 3: 3, 6, 9, 12...
- Multiples of 6: 6, 12, 18...
- Multiples of 9: 9, 18, 27...
Merge and dedupe: 3, 6, 9, 12, 15, 18... Notice that 6 and 9 don't add anything new before 12 โ they're both multiples of 3, so they were already going to appear as multiples of 3 anyway. The third smallest amount in the merged list is 9.
That overlap โ 6 and 9 already showing up as multiples of 3 โ is the whole crux of the problem. The more coins you add, the messier this overlap gets, and untangling it by brute-force merging is where the naive approach falls apart.
Intuition
The instinct most people reach for first is: generate multiples of every coin, throw them in a set to kill duplicates, sort, and index into position k. It works on the example. It will not work on the actual constraints, because k can be 2 billion โ you'd be building and sorting a list with billions of entries before you could even answer the question.
The way out is to stop thinking about generating amounts and start thinking about counting them. Instead of asking "what is the k-th amount?", ask a different, answerable question: "how many valid amounts are less than or equal to some number x?" If you can answer that count quickly for any x, you can binary search for the smallest x where the count reaches k โ and that x is your answer.
This is the same shift that shows up in "find the k-th smallest element in a sorted matrix" or "find the smallest capacity that lets you ship packages within D days" โ whenever direct enumeration is too expensive but a counting function is cheap and monotonic, binary search on the answer becomes the tool.
The remaining puzzle is how to count correctly. If you naively count multiples of 3 up to x, then add multiples of 4 up to x, you double-count anything that's a multiple of both โ like 12. This is the classic overlap problem: 5 people won prize A, 4 people won prize B, but 2 people won both, so the real total of distinct winners is 5 + 4 โ 2, not 9. Multiples of 3 and 4 overlap exactly on multiples of their least common multiple (LCM), which is 12. Subtract those once, and the count is exact.
With more than two coins, this generalizes into inclusion-exclusion: add the counts for each single coin, subtract the counts for each pair (using their LCM), add back the counts for each triple, and so on, alternating sign by subset size. Every subset's LCM tells you which multiples were over- or under-counted, and the alternating signs cancel out every duplicate exactly once.
Brute Force Solution
Idea: Generate multiples of every coin up to some bound, merge them into a set to remove duplicates, sort, and return the k-th element.
Algorithm:
- Pick an upper bound large enough to guarantee at least k valid amounts exist below it.
- For each coin, generate every multiple up to that bound.
- Insert all multiples into a set (this naturally deduplicates overlapping multiples like 12).
- Sort the set and index into position
k - 1.
Advantages: Trivial to reason about, easy to verify against small examples, no math beyond basic multiplication.
Disadvantages: The list size scales with k itself, and k can reach 2 billion โ the set and the sort both become infeasible in both time and memory.
Complexity: Time is roughly O(k log k) for building and sorting, and space is O(k) for storing the amounts. Both are unworkable at the given constraints.
Optimal Solution
The optimal solution has two parts working together: a count function that answers "how many valid amounts are โค x" using inclusion-exclusion, and a binary search that uses that count function to home in on the exact k-th value.
Count function (inclusion-exclusion over subsets of coins):
For every non-empty subset of coins, compute the LCM of that subset. The number of multiples of that LCM up to x is x // lcm. Add this count if the subset size is odd, subtract it if the subset size is even. Summing over all subsets gives the exact count of amounts โค x that are payable by at least one coin, with no double-counting.
| Subset | LCM | Sign | Contribution |
|---|---|---|---|
| {3} | 3 | + | x // 3 |
| {4} | 4 | + | x // 4 |
| {3, 4} | 12 | โ | x // 12 |
Binary search on x:
- Set
lo = 1andhito a value large enough to guarantee the count reaches k (the smallest coin times k is a safe upper bound). - While
lo < hi, computemid = (lo + hi) // 2. - If
count(mid) >= k, the answer is at or belowmid, so sethi = mid. - Otherwise set
lo = mid + 1. - When
lo == hi, that value is the k-th smallest valid amount.
This works because the count function is monotonically non-decreasing as x grows โ larger x can only include more valid amounts, never fewer. That monotonicity is exactly what makes binary search valid here.
Python Code
from itertools import combinations
from math import lcm
from typing import List
def findKthSmallest(coins: List[int], k: int) -> int:
n = len(coins)
def count_at_most(x: int) -> int:
total = 0
for size in range(1, n + 1):
sign = 1 if size % 2 == 1 else -1
for combo in combinations(coins, size):
total += sign * (x // lcm(*combo))
return total
lo, hi = 1, min(coins) * k
while lo < hi:
mid = (lo + hi) // 2
if count_at_most(mid) >= k:
hi = mid
else:
lo = mid + 1
return lo
Code Walkthrough
count_at_most(x)implements inclusion-exclusion: it loops over every subset size from 1 to n, and within each size, over every combination of coins of that size.signalternates based on subset size โ positive for odd sizes (single coins, triples...), negative for even sizes (pairs, quadruples...), which is exactly what cancels out double-counted multiples.lcm(*combo)computes the least common multiple of the coins in that subset; Python'smath.lcmaccepts multiple arguments directly, so no manual GCD chaining is needed.x // lcm(*combo)counts how many multiples of that LCM are โค x โ the raw count for that subset's contribution.- The binary search bounds
lo = 1andhi = min(coins) * kguarantee the answer is inside the range, since the k-th multiple of the smallest coin is always an upper bound on the true answer. - The loop narrows
[lo, hi]until they meet, using the standard "search for smallest x where predicate is true" binary search template.
Dry Run
Coins [3, 4], k = 5.
lo = 1,hi = 3 * 5 = 15.mid = 8: count = (8//3) + (8//4) โ (8//12) = 2 + 2 โ 0 = 4. That's less than 5, solo = 9.mid = 12: count = (12//3) + (12//4) โ (12//12) = 4 + 3 โ 1 = 6. That's โฅ 5, sohi = 12.mid = 10: count = (10//3) + (10//4) โ (10//12) = 3 + 2 โ 0 = 5. That's โฅ 5, sohi = 10.mid = 9: count = (9//3) + (9//4) โ (9//12) = 3 + 2 โ 0 = 5. That's โฅ 5, sohi = 9.lo == hi == 9. The answer is 9.
Checking by hand: multiples of 3 are 3, 6, 9, 12...; multiples of 4 are 4, 8, 12...; merged and sorted: 3, 4, 6, 8, 9 โ the 5th value is 9. Matches.
Complexity Analysis
Time: For each binary search step, count_at_most iterates over all 2^n โ 1 non-empty subsets of coins, computing an LCM per subset. With n up to 15, that's roughly 32,000 subsets per check. Binary search runs in about O(log(range)) steps โ around 40 iterations for a range up to min(coins) * k with k up to 2 billion. Total time is O(2^n ยท log(range)), comfortably fast because n is capped small.
Space: Only O(n) for tracking the current subset during combination generation โ no list of amounts is ever built.
Why it's correct: Inclusion-exclusion guarantees an exact count with no double-counting, and the count function is monotonic in x, which is the exact precondition binary search requires to converge on the correct boundary.
Alternative Solutions
A heap-based k-way merge (repeatedly popping the smallest unseen multiple across all coins, skipping duplicates) is a middle ground โ it avoids generating a fully sorted list upfront, but it still does O(k) pop operations, which is a dealbreaker when k reaches 2 billion. It's worth mentioning in an interview as a "better than brute force but still not good enough" step, since it shows you understand the scaling problem before landing on the binary-search-on-count approach.
Edge Cases
- Single coin: With only one denomination, the count function reduces to
x // coin, and the answer is simplycoin * k. - k = 1: The answer is always the smallest coin value, since it's the smallest amount payable by definition.
- Coins sharing a common factor: If every coin shares a factor (like 6, 10, 14 all being even), the LCMs and counts shift, but the binary search bounds stay valid โ the smallest coin times k is still a safe upper bound.
- Maximum coins (15) and maximum k (2ร10^9): This is the stress case that breaks brute force; the optimal solution stays fast because its cost depends on 2^n, not k.
- Duplicate LCMs across different subsets: Since coins are guaranteed distinct, this doesn't cause incorrect cancellation, but it's worth double-checking your subset generation doesn't accidentally skip or repeat a combination.
Common Mistakes
- Forgetting to alternate the sign by subset size, which causes systematic over- or under-counting.
- Computing LCM incorrectly by summing or averaging instead of using the proper
lcm(a, b) = a * b // gcd(a, b)relationship (ormath.lcmdirectly). - Setting the binary search upper bound too low, so the true answer falls outside the search range.
- Using
count(mid) > kinstead ofcount(mid) >= kin the binary search condition, which breaks the "smallest x satisfying the predicate" invariant. - Attempting to actually build and sort the merged list of amounts, which silently works on small examples but times out or exhausts memory on the real constraints.
Interview Questions
- What property must
count_at_most(x)have for binary search to be valid here, and why? - How does the time complexity change if the number of coins grows from 15 to, say, 30?
- Could you solve this with a min-heap instead of inclusion-exclusion? What's the tradeoff?
- If all coins are guaranteed to share a common factor, does that change your binary search bounds or just your counting logic?
- How would you extend this to answer "how many valid amounts exist in a range [a, b]" instead of just up to x?
Similar Problems
- LeetCode 1201 โ Ugly Number III: Nearly identical structure โ count multiples of up to three numbers using inclusion-exclusion, then binary search for the k-th ugly number.
- LeetCode 1283 โ Find the Smallest Divisor Given a Threshold: Same "binary search on the answer with a monotonic check function" pattern, applied to a division-sum constraint instead of counting.
- LeetCode 719 โ Find K-th Smallest Pair Distance: Another k-th-value problem where direct enumeration is too slow, solved by binary searching a distance and counting pairs within it.
- LeetCode 378 โ Kth Smallest Element in a Sorted Matrix: The same counting-instead-of-generating idea, applied to a 2D sorted grid.
Key Takeaways
When the answer space is too large to enumerate but you can cheaply count how many candidates satisfy "at most x," binary search on x is almost always the move. Inclusion-exclusion is the tool for counting union sizes without double-counting overlaps, and it pairs naturally with problems built on multiples, divisors, or LCMs. The subset count (2^n) being small here is what makes the whole approach tractable โ always check which variable in the problem is actually small before deciding your algorithm's complexity around it.
Watch the Video
For the full walkthrough โ including a live timing comparison between brute force and the optimal solution on a real 15-coin input โ watch the video here: {LINK}
About the Series
This breakdown is part of Fun with Learning Technology, a series dedicated to building real algorithmic intuition instead of memorized solutions โ tracing how an experienced engineer actually arrives at an optimal approach, one problem at a time.
Call To Action
If this helped the inclusion-exclusion and binary-search-on-answer pattern click, give the video a like on YouTube and subscribe for more deep dives like this one. For the full write-ups delivered straight to your inbox, subscribe to the Substack. Drop a comment with your own approach or a problem you'd like covered next, and share this with anyone prepping for interviews.
The solution
class Solution:
def findKthSmallest(self, coins, k):
from itertools import combinations
from math import lcm
def count(x):
total = 0
for size in range(1, len(coins) + 1):
for combo in combinations(coins, size):
l = lcm(*combo)
total += (x // l) if size % 2 else -(x // l)
return total
lo, hi = 1, min(coins) * k
while lo < hi:
mid = (lo + hi) // 2
if count(mid) >= k:
hi = mid
else:
lo = mid + 1
return loReady to try it yourself? Solve Binary problems with instant feedback in the practice sandbox.
Practice now โ


