✅ 🎯 📌 Simple Solution || Bits || Fastest Solution ✅ 🎯 📌
Code
# Code\n```python3 []\nclass CombinationIterator:\n\n    def __init__(self, characters: str, combinationLength: int):\n        # save variables\n        self.c=combinationLength\n        self.l=list(characters)\n\n        # create a number which represents the first combination when read in binary format\n        self.idx=0\n\n        # first all 1s to the left\n        for i in range(self.c):\n            self.idx<<=1\n            self.idx+=1\n\n        # pad with 0s on the right to get proper length\n        for i in range(len(self.l)-self.c):\n            self.idx<<=1\n\n    def next(self) -> str:\n        # get binary representation\n        b=bin(self.idx)[2:]\n\n        # convert to string by selecting 1 marked characters (remember to pad binary format with 0 on left)\n        ans=\'\'.join([i for i,j in zip(self.l,\'0\'*(len(self.l)-len(b))+b) if j==\'1\'])\n\n        # get to next value in the sequence\n        self.idx-=1\n        # reduce while bit count is not the required number of characters\n        # this ensures we follow the proper combination order\n        while self.idx.bit_count()!=self.c: self.idx-=1\n\n        return ans\n        \n\n    def hasNext(self) -> bool:\n        # if index points to values greater than last possible value, return True\n        return self.idx>=((1<<self.c)-1)\n\n\n# Your CombinationIterator object will be instantiated and called as such:\n# obj = CombinationIterator(characters, combinationLength)\n# param_1 = obj.next()\n# param_2 = obj.hasNext()\n```
['String', 'Backtracking', 'Design', 'Iterator', 'Python3']