Iterator for Combination - Solution & Explanation
Problem Statement
Design the CombinationIterator class:
CombinationIterator(string characters, int combinationLength)Initializes the object with a stringcharactersof sorted distinct lowercase English letters and a numbercombinationLengthas arguments.next()Returns the next combination of lengthcombinationLengthin lexicographical order.hasNext()Returnstrueif and only if there exists a next combination.
Example 1:
Input
["CombinationIterator", "next", "hasNext", "next", "hasNext", "next", "hasNext"]
[["abc", 2], [], [], [], [], [], []]
Output
[null, "ab", true, "ac", true, "bc", false]
Explanation
CombinationIterator itr = new CombinationIterator("abc", 2);
itr.next(); // return "ab"
itr.hasNext(); // return True
itr.next(); // return "ac"
itr.hasNext(); // return True
itr.next(); // return "bc"
itr.hasNext(); // return False
Constraints:
1 <= combinationLength <= characters.length <= 15- All the characters of
charactersare unique. - At most
104calls will be made tonextandhasNext. - It is guaranteed that all calls of the function
nextare valid.
Approach Overview
Problem Overview: Design an iterator that returns all combinations of length k from a given sorted string of characters. Each call to next() should return the next combination in lexicographical order, and hasNext() should indicate whether more combinations remain.
Approach 1: Precompute All Combinations (Time: O(C(n,k) * k), Space: O(C(n,k) * k))
This approach generates every valid combination during initialization using backtracking. Start from index 0, recursively build a string by choosing the next character and continuing until the length reaches k. Each completed combination is appended to a list. Because the input string is already sorted, the generated combinations naturally appear in lexicographic order. The iterator then simply maintains an index pointer: next() returns the current element and increments the pointer, while hasNext() checks whether the pointer is within bounds.
The main advantage is simplicity. Once the combinations are precomputed, each iterator call is constant time. The tradeoff is memory usage because all C(n,k) combinations are stored upfront.
Approach 2: Generate Combinations on the Fly (Time: O(C(n,k) * k), Space: O(k))
This approach generates the next combination only when needed instead of storing all results. Maintain an array of indices representing the current combination. Initially it contains [0,1,2,...,k-1]. When next() is called, build the string using those indices from the original characters.
To compute the next state, scan the indices from right to left and find the first position that can be incremented without exceeding its limit. Increase that index and reset all positions to its right to the smallest valid increasing sequence. This logic is similar to generating the next lexicographical combination and works well with an iterator design pattern. Only the current index array is stored, so the memory footprint stays small.
This technique avoids storing every combination and is typically preferred when the number of combinations is large. The time cost shifts from initialization to each call to next(), but each step still runs in about O(k).
Recommended for interviews: Interviewers usually expect the on‑the‑fly generation approach because it demonstrates understanding of string combination generation and iterator state management. Implementing the precomputation method first is still valuable because it proves you understand how combinations are formed. The optimized iterator version shows stronger design and algorithmic reasoning.
Approach 1: Precompute All Combinations
In this approach, we precompute all the combinations of the given string of a specified length. This allows us to provide the next combination in constant time by just iterating over the precomputed list. For this, we can use recursion or libraries to generate combinations initially and store them in an internal data structure.
To find all combinations of a particular length, you can use backtracking or an iterative process that resembles a binary-like increase in combinations selection.
This Python solution uses the itertools.combinations library to generate all the combinations of the given length at the initialization stage. Whenever next() is called, it returns the current combination and advances the index.
Complexity
Time Complexity: O(n!) for precomputation, O(1) for next and hasNext.
Space Complexity: O(n!) due to storage of combinations.
Approach 2: Generate Combinations on The Fly
Instead of generating all combinations at once, we can generate them on the fly when next() is called. This approach uses bit manipulation to generate the combination efficiently by representing each combination as a bitmask. However, this requires understanding how to generate valid combinations incrementally with proper bit manipulation.
This C# solution uses an indices array to represent the current combination. It simulates the generation of combinations by modifying the indices array with each call to next(). When there is a valid combination, the indices are updated to represent the next viable combination.
Code
C#
JavaScript
Complexity
Time Complexity: O(1) for next and hasNext, average complexity due to combination generation logic.
Space Complexity: O(combinationLength), the storage used for the indices.
Approach 3: Default Approach
Try this approach in the editor →Complexity Comparison
| Approach | Complexity |
|---|---|
| Precompute All Combinations | Time Complexity: |
| Generate Combinations on The Fly | Time Complexity: |
| Default Approach | — |
Detailed Complexity Analysis
| Approach | Time | Space | When to Use |
|---|---|---|---|
| Precompute All Combinations | O(C(n,k) * k) | O(C(n,k) * k) | When simplicity matters and memory is not a constraint |
| Generate Combinations on the Fly | O(C(n,k) * k) | O(k) | When the number of combinations is large and memory should remain minimal |
Video Solution
Iterator for combination | BitMasking | Backtracking | Leetcode #1286 • Techdose • 4,937 views views
Watch 9 more video solutions →Frequently Asked Questions
Is Iterator for Combination easy or hard?
Iterator for Combination Python/Java solution
How to solve Iterator for Combination in O(n)?
What is the best approach for Iterator for Combination?
Is Iterator for Combination asked at Google/Amazon/Meta?
What data structure is used in Iterator for Combination?
What is the time complexity of Iterator for Combination?
Ready to solve this problem?
Practice Iterator for Combination with our built-in code editor and test cases.
Practice on FleetCode