Find the longest substring with k unique characters in a given string

Given a string you need to print longest possible substring that has exactly M unique characters. If there are more than one substring of longest possible length, then print any one of them.

Examples:

"aabbcc", k = 1
Max substring can be any one from {"aa" , "bb" , "cc"}.

"aabbcc", k = 2
Max substring can be any one from {"aabb" , "bbcc"}.

"aabbcc", k = 3
There are substrings with exactly 3 unique characters
{"aabbcc" , "abbcc" , "aabbc" , "abbc" }
Max is "aabbcc" with length 6.

"aaabbb", k = 3
There are only two unique characters, thus show error message. 
class Solution {
    public int lengthOfLongestSubstringKDistinct(String str, int k) {
        if (k == 0 || str.length() == 0)
            return "";
        HashMap<Character, Integer> map = new HashMap<>();
        int start = 0, unique = 0;
        int maxLen = 0, maxStart = -1;
        for (int i = 0; i < str.length(); i++) {
            char x = str.charAt(i);
            if (!map.containsKey(x) || map.get(x) == 0)
                unique++;
            map.put(x, map.getOrDefault(x, 0) + 1);
            // Removing characters from start of our window until the number
            // of unique chars > K
            while (unique > k) {
                map.put(str.charAt(start), map.get(str.charAt(start)) - 1);
                if (map.get(str.charAt(start)) == 0) {
                    map.remove(str.charAt(start));
                    unique--;
                }
                start++;
            }
            if (unique == K && (i - start + 1) > maxLen) {
                maxLen = i - start + 1;
                maxStart = start;
            }
        }
        return maxStart == -1 ? "" : str.substring(maxStart, maxStart + maxLen);
    }
}

Last updated