Find the longest substring with k unique characters


Longest Substring with K Unique Characters – GFG


Problem Statement

Given a string s consisting only of lowercase alphabets and an integer k, find the length of the longest substring that contains exactly k distinct characters.

If no such substring exists, return -1.


Examples


Constraints


Intuition

This problem fits the Variable Size Sliding Window with Hash Table Lookup pattern:


Approach

  1. Use two pointers l and r to represent the sliding window.

  2. Use a HashMap<Character, Integer> to track the frequency of characters in the current window.

  3. Expand the window by moving r forward:

    • Add s[r] to the map and update its frequency.
  4. While the map size > k, shrink the window from the left:

    • Decrease the frequency of s[l]

    • If frequency becomes 0, remove it from the map

    • Move l forward

  5. If the map size == k, update the maxLen with the current window size.

  6. After the loop ends, return maxLen if updated, else return -1.


Java Code

class Solution {
    public int longestkSubstr(String s, int k) {
        int l = 0, r = 0;
        int maxLen = -1;
        Map<Character, Integer> map = new HashMap<>();

        while (r < s.length()) {
            char ch = s.charAt(r);
            map.put(ch, map.getOrDefault(ch, 0) + 1);

            while (map.size() > k) {
                char leftChar = s.charAt(l);
                map.put(leftChar, map.get(leftChar) - 1);
                if (map.get(leftChar) == 0) {
                    map.remove(leftChar);
                }
                l++;
            }

            if (map.size() == k) {
                maxLen = Math.max(maxLen, r - l + 1);
            }

            r++;
        }

        return maxLen;
    }
}

Time and Space Complexity


Dry Run

Input:

s = "aabacbebebe", k = 3

Steps:

  1. "aabac" → Map: {a, b, c} → Valid → Length = 5

  2. "abacb" → Valid → Length = 5

  3. "bacbe" → Valid → Length = 5

  4. "acbeb" → Valid → Length = 5

  5. "cbebebe" → Map: {c, b, e} → Valid → Length = 7 (update max)

Output: 7


Conclusion

This problem is a classic Variable Size Sliding Window with Hash Table scenario where:

This pattern is frequently used in problems like: