O(K) DP solution. Faster and Lighter than 100%
\n/*\n        for String = "abcd" and combination Length = 3, our DP table will look like this -\n        [1, 1, 1, 1]\n        [3, 2, 1, 0]\n        [3, 1, 0, 
```\n/*\n        for String = "abcd" and combination Length = 3, our DP table will look like this -\n        [1, 1, 1, 1]\n        [3, 2, 1, 0]\n        [3, 1, 0, 0]\n\t\t\n\t\tdp(i, j) = number of combination string possible of length "i+1" from j\'th character in original string \n\t\t\n\t\teg. \n\t\tdp[1][0] = 3, it stores how many combination is possible of length 2 when we start from \'a\' in our original string "abcd"\n\t\tthese three combinations are -> "ab", "ac", "ad";\n        \n\t\tNow for solution to this problem, we will calculate total number of combination possible for length combinationLength;\n\t\tIn our example we have total = 3 + 1 + 0 + 0  = 4 total combination possible, these are "abc", "abd", "acd", "bcd";\n\t\t\n\t\twe will maintain a pointer "ptr" for current possible combination;\n\t\tfor Every next() function we will calculate ptr\'th combination, so for ptr = 3 next() should return "acd";\n\t\t\n\t\twe will use DP table to compute our combination from ptr;\n\t\t\n\t\tNow, We need a string of length combLen.  We will lookup in combLen-1\'th row. \n\t\t* If dp[i][j] value is lesser than our "ptr" then our combination is not in that range.\n\t\t* If dp[i][j] values is greater than or equal than "ptr", then our combinatino is in that range. Hence we will add that character. And Now, we will look for combination with length (combLen-1) (Meaing one row above in DP table);\n\t\t\n\t\tYou will get much more clarity if you dry run a case yourself.\n*/\nclass CombinationIterator {\n    static int[][] dp;\n    static int combLen; //lenght of the string of Output  //K\n    static int total;   // total number of combinations\n    static int ptr;     // pointer for current combination \n    static String str;  //original string\n    \n    public CombinationIterator(String characters, int combinationLength) {\n        int n = characters.length();\n        str = characters;\n        \n        combLen = combinationLength;\n        dp = new int[combLen][n];\n\n        \n        for(int i = 0; i < n; i++) dp[0][i] = 1;\n        for(int i = 1; i < combLen; i++) {\n            for(int j = n-1-i; j >= 0; j--) {\n                dp[i][j] = dp[i-1][j+1] + dp[i][j+1];\n            }\n        }\n        \n\t\t//calculating total combination possible of length -> combinationLength\n        total = 0;\n        ptr = 1;\n        for(int i = 0; i < n; i++) total += dp[combLen-1][i];\n    }\n    \n    public String next() {\n        int curr = ptr;\n        \n        char[] arr = new char[combLen];\n        int idx = 0;\n        \n        int i = combLen-1, j = 0;\n        while(idx < combLen) {\n            if(curr > dp[i][j]) {\n                curr -= dp[i][j];\n            }else {\n                arr[idx++] = str.charAt(j);\n                i--;\n            }\n            j++;\n        }\n        \n        ptr++;\n        return new String(arr);\n    }\n    \n    public boolean hasNext() {\n        return ptr <= total;\n    }\n}\n\n/**\n * Your CombinationIterator object will be instantiated and called as such:\n * CombinationIterator obj = new CombinationIterator(characters, combinationLength);\n * String param_1 = obj.next();\n * boolean param_2 = obj.hasNext();\n */\n```
['Dynamic Programming', 'Java']