LeetCode Problem Workspace
Iterator for Combination
Implement an iterator that generates all combinations of a given length using efficient backtracking with pruning.
4
Topics
4
Code langs
3
Related
Practice Focus
Medium · Backtracking search with pruning
Answer-first summary
Implement an iterator that generates all combinations of a given length using efficient backtracking with pruning.
Ace coding interviews with Interview AiBoxInterview AiBox guidance for Backtracking search with pruning
This problem requires building a CombinationIterator class that returns all possible combinations of a string of a fixed length. The key is using backtracking with pruning to precompute valid sequences, allowing next() and hasNext() calls to run in constant time. Careful handling of string indices ensures correctness while avoiding unnecessary computation during iteration.
Problem Statement
Design a CombinationIterator class for a string of unique characters and a fixed combination length. The iterator should return combinations in lexicographical order and support next() and hasNext() operations efficiently.
Implement the class with the following behavior: next() returns the next combination string, hasNext() checks if more combinations are available, and all operations must be optimized for multiple calls while adhering to the constraints on input size and uniqueness.
Examples
Example 1
Input: See original problem statement.
Output: See original problem statement.
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 characters are unique.
- At most 104 calls will be made to next and hasNext.
- It is guaranteed that all calls of the function next are valid.
Solution Approach
Precompute all combinations with backtracking
Use backtracking to generate all valid combinations of the given length. Apply pruning by skipping branches once the remaining characters cannot fulfill the required combination length. Store results in a queue or list to support fast iteration through next().
Use an index pointer for iteration
Maintain an internal pointer to track the current combination in the precomputed list. next() increments the pointer and returns the combination, while hasNext() checks if the pointer is still within bounds. This avoids recomputation and guarantees O(1) per call.
Optimize memory and call limits
Given the constraints on string length and number of calls, ensure that precomputing all combinations is feasible. Avoid storing redundant data and leverage lazy evaluation only if needed to reduce space usage while maintaining constant-time next() access.
Complexity Analysis
| Metric | Value |
|---|---|
| Time | Depends on the final approach |
| Space | Depends on the final approach |
Time complexity is O(C(n, k)) to precompute all combinations, where n is characters.length and k is combinationLength. Each next() and hasNext() call is O(1). Space complexity is also O(C(n, k)) to store all combinations for efficient iteration.
What Interviewers Usually Probe
- They may ask about handling large input strings and optimizing precomputation.
- Expect clarification questions on lexicographical ordering and index management.
- They may probe memory trade-offs between storing all combinations versus generating on the fly.
Common Pitfalls or Variants
Common pitfalls
- Failing to prune branches during backtracking, leading to unnecessary computation.
- Incorrect pointer management causing next() to skip or repeat combinations.
- Ignoring lexicographical order in the combination generation.
Follow-up variants
- Generate combinations lazily without precomputing to reduce memory usage.
- Allow duplicate characters in the input string, requiring additional checks.
- Support variable-length combinations instead of a fixed length.
FAQ
What is the main pattern in Iterator for Combination?
The key pattern is backtracking search with pruning to generate all combinations efficiently and in lexicographical order.
How do I ensure next() and hasNext() are fast?
Precompute all combinations using backtracking and store them in a list or queue, allowing O(1) next() and hasNext() operations.
What should I watch out for with lexicographical order?
Maintain the order during backtracking by always choosing characters in increasing index order to ensure correct sequence generation.
Can this approach handle maximum input constraints?
Yes, with n <= 15, precomputing all C(n, k) combinations is feasible and fits within memory limits.
Is lazy combination generation better than precomputing?
Lazy generation saves space but adds complexity; for this problem, precomputing is preferred to achieve constant-time iteration.
Solution
Solution 1
#### Python3
class CombinationIterator:
def __init__(self, characters: str, combinationLength: int):
def dfs(i):
if len(t) == combinationLength:
cs.append(''.join(t))
return
if i == n:
return
t.append(characters[i])
dfs(i + 1)
t.pop()
dfs(i + 1)
cs = []
n = len(characters)
t = []
dfs(0)
self.cs = cs
self.idx = 0
def next(self) -> str:
ans = self.cs[self.idx]
self.idx += 1
return ans
def hasNext(self) -> bool:
return self.idx < len(self.cs)
# Your CombinationIterator object will be instantiated and called as such:
# obj = CombinationIterator(characters, combinationLength)
# param_1 = obj.next()
# param_2 = obj.hasNext()Solution 2
#### Python3
class CombinationIterator:
def __init__(self, characters: str, combinationLength: int):
def dfs(i):
if len(t) == combinationLength:
cs.append(''.join(t))
return
if i == n:
return
t.append(characters[i])
dfs(i + 1)
t.pop()
dfs(i + 1)
cs = []
n = len(characters)
t = []
dfs(0)
self.cs = cs
self.idx = 0
def next(self) -> str:
ans = self.cs[self.idx]
self.idx += 1
return ans
def hasNext(self) -> bool:
return self.idx < len(self.cs)
# Your CombinationIterator object will be instantiated and called as such:
# obj = CombinationIterator(characters, combinationLength)
# param_1 = obj.next()
# param_2 = obj.hasNext()Continue Topic
string
Practice more edge cases under the same topic.
arrow_forwardauto_awesomeContinue Pattern
Backtracking search with pruning
Expand the same solving frame across more problems.
arrow_forwardsignal_cellular_altSame Difficulty Track
Medium
Stay on this level to stabilize interview delivery.
arrow_forward