Iterator for Combination | C++ Pointers Solution with Set for duplicates
The idea is to create a list of pointers, that will indicate how to construct the next combination string.\nThe list has initial values of {0, 1, 2, 3,..., n - 
The idea is to create a list of pointers, that will indicate how to construct the next combination string.\nThe list has initial values of ```{0, 1, 2, 3,..., n - 1}``` where ```n``` is the ```combinationsLength``` input.\nEach ```int``` value in the list represents an index of one of the characters from the input.\n\nMaximum value for each position ```i``` in the pointer list is ```characters.length() - combinationsLength + i```, because if the starting pointer has a value that is closer to the end of the combination string than there are characters left in the input string, it couldn\'t complete the combination string anyway. (e.g. Input ```["abcde", 3]``` => max values for pointers is ```{2, 3, 4}```, because we cannot have ```{3, 4, 5}``` or higher)\n\n<b>Example</b>\nInput: ```characters = "aabcd"``` and ```combinationLength = 3```\nPointers initialized to ```{0, 1, 2}```\n\n```next()``` is called. First we read the combination according to the values in the pointer list.\n0 -> a\n1 -> a\n2 -> b\nThe word ```aab``` is returned. Then we increment the pointers, starting from the last index in the pointer list. Look at the value at the last index ```(2)```, it has the value ```2```, while the maximum value for that index is ```characters.length() - combinationsLength + i = 5 - 3 + 2 = 4```. That means we can increment the value and move on. The pointer list is now ```{0, 1, 3}```.\n\nWhen ```next()``` is called again, we do the same procedure as the first time.\n0 -> a\n1 -> a\n3 -> c\nThe word ```aac``` is returned. After incrementing the pointer list, it has the following values ```{0, 1, 4}```.\n\n```next()``` is called again. The returned word is ```aad```. This time we cannot increment the value at the last index, so we move on to the next one on the left. It has a value of ```1``` and it can be incremented. The trick here is to reset all the values that have a higher index than the current one, by setting every value at index ```i``` to the value of the previous index ```i - 1``` plus one.  We do it every time a pointer value is incremented, but it was skipped in the first few cases, because there weren\'t any elements with a higher index, since it was the last element in the list.\nThe list should now look like this ```{0, 2, 3}```. When ```next()``` is called again, it returns ```abc```.\n\nTo clarify more, another example of resetting the values of all elements with higher index in the pointer list:\nIf the pointer list is ```{0, 3, 4}``` and it is time for us to increment the pointers, the next value to increment is at index ```0``` with the value ```0```, so after incrementing, it will have a value of ```1```. Then the value of index ```1``` will have a value of ```pointers[i - 1] + 1```, which is ```2```. The value at index ```2```, will get the value ```3```, resulting in pointer list ```{1, 2, 3}```. \n\n<b> Duplicates </b>\nEvery time we are retrieving the next combination string, we check if that string was already created. If it was, we increment the pointer list and get the next string to check, otherwise we add the new string to the set.\n\nI would greatly appreciate it if I get advice or suggestions on how I can improve the solution.\n\n```\nclass CombinationIterator {\nprivate:\n    string chars;\n    int size, combLen;\n    bool nextExists;\n    vector<int> pointers; // Use pointers to know which letters to get for the next combination.\n    unordered_set<string> combSet; // Use set to skip duplicates.\n\n    // Set pointers list to starting values {0, 1, 2, 3,..., n - 1} for n = combinationsLength.\n    void initPointers() {\n        for (int i = 0; i < combLen; i++)\n            pointers.push_back(i);\n    }\n\n    void incrementPointers() {\n        // Go from right to left in the pointers list and increment the first pointer\n        // that won\'t cross it\'s maximum value.\n        // Max value for each position i in the pointers list is characters.length() - combinationsLength + i.\n        // e.g. Input ["abcde", 3] => max values for pointers is {2, 3, 4}.\n        for (int i = combLen - 1, j = 0; i >= 0; i--) {\n            if (pointers[i] + 1 < size - j++) {\n                pointers[i]++;\n\n                // Reset the values of all pointers with a higher index\n                for (int n = i + 1; n < combLen; n++) {\n                    pointers[n] = pointers[n - 1] + 1;\n                }\n                return;\n            }\n        }\n        // If pointers cannot increment anymore, there are no more combinations.\n        nextExists = false;\n    }\n\n    string readNextCombination() {\n        string nextStr;\n        bool newCombinationFound = false;\n\n        // Construct the string based on the current pointer values.\n        // If the new string is already in the set, increment pointers and repeat the process.\n        while (!newCombinationFound) {\n            nextStr = "";\n            for (int i = 0; i < combLen; i++)\n                nextStr += chars[pointers[i]];\n\n            newCombinationFound = combSet.find(nextStr) == combSet.end();\n            \n            if (!newCombinationFound) { \n                incrementPointers();\n                if (!nextExists) return "";\n            }\n        }\n        combSet.insert(nextStr);\n        return nextStr;\n    }\n\npublic:\n    CombinationIterator(string characters, int combinationLength) {\n        this->chars = characters;\n        this->size = characters.length();\n        this->combLen = combinationLength;\n        this->nextExists = true;\n        initPointers();\n    }\n\n    string next() {\n        if (!nextExists) return "";\n\n        string nextStr = readNextCombination();\n        incrementPointers();\n        return nextStr;\n    }\n\n    bool hasNext() {\n        return nextExists;\n    }\n};\n```
[]