1286. Iterator for Combination
Design the CombinationIterator class:
- CombinationIterator(string characters, int combinationLength) Initializes the object with a string characters of sorted distinct lowercase English letters and a number combinationLength as arguments.
- next() Returns the next combination of length combinationLength in lexicographical order.
- hasNext() Returns true if 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 characters are unique.
- At most 10 4 10^4 104 calls will be made to next and hasNext.
- It is guaranteed that all calls of the function next are valid.
From: LeetCode
Link: 1286. Iterator for Combination
Solution:
Ideas:
Store the current character indices, then increment the rightmost index that can still move forward.
Code:
c
typedef struct {
char* characters;
int* indices;
int n;
int k;
bool hasNext;
} CombinationIterator;
CombinationIterator* combinationIteratorCreate(char* characters, int combinationLength) {
CombinationIterator* obj =
(CombinationIterator*)malloc(sizeof(CombinationIterator));
obj->n = strlen(characters);
obj->k = combinationLength;
obj->hasNext = true;
obj->characters = (char*)malloc((obj->n + 1) * sizeof(char));
strcpy(obj->characters, characters);
obj->indices = (int*)malloc(obj->k * sizeof(int));
for (int i = 0; i < obj->k; i++) {
obj->indices[i] = i;
}
return obj;
}
char* combinationIteratorNext(CombinationIterator* obj) {
char* result = (char*)malloc((obj->k + 1) * sizeof(char));
for (int i = 0; i < obj->k; i++) {
result[i] = obj->characters[obj->indices[i]];
}
result[obj->k] = '\0';
int i = obj->k - 1;
while (i >= 0 &&
obj->indices[i] == obj->n - obj->k + i) {
i--;
}
if (i < 0) {
obj->hasNext = false;
} else {
obj->indices[i]++;
for (int j = i + 1; j < obj->k; j++) {
obj->indices[j] = obj->indices[j - 1] + 1;
}
}
return result;
}
bool combinationIteratorHasNext(CombinationIterator* obj) {
return obj->hasNext;
}
void combinationIteratorFree(CombinationIterator* obj) {
free(obj->characters);
free(obj->indices);
free(obj);
}