Understanding the Problem
We are given a string s
and an integer k
. Our goal is to find the length of the longest substring of s
that contains at most k
distinct characters.
Think of a substring as a piece of the original string that comes in a continuous block. The constraint is that this block can have at most k
different letters.
If k
is 0 or if the string is empty, it means no characters can be part of the substring — so we return 0 immediately.
We will use the sliding window technique with two pointers (start
and end
) to maintain a valid window and a hash map
to count character frequency.
Step-by-Step Solution with Example
Step 1: Initialize
We start by initializing:
- A map called
charFreq
to store how many times each character appears in our window.
start = 0
and end
will iterate through the string.
maxLen = 0
to track the longest valid substring.
Step 2: Traverse the String
We iterate through the string one character at a time using end
. At each step:
- Add
s[end]
to the charFreq
map and update its count.
- Check: if the number of distinct keys in
charFreq
exceeds k
, the window is no longer valid.
Step 3: Shrink Window
While the window is invalid (i.e., we have more than k
distinct characters), we shrink it from the left:
- Decrease the count of
s[start]
in the map.
- If the count becomes zero, remove that character from the map.
- Move
start
forward by one.
Step 4: Update Max Length
At each valid window, calculate the window size (end - start + 1)
and update maxLen
if it's larger than the previous value.
Step 5: Example Walkthrough
Let's take s = "eceba"
, k = 2
Window: "e" → {'e':1} → valid → maxLen = 1
Window: "ec" → {'e':1, 'c':1} → valid → maxLen = 2
Window: "ece" → {'e':2, 'c':1} → valid → maxLen = 3
Window: "eceb" → {'e':2, 'c':1, 'b':1} → invalid → shrink
Shrink to "ceb" → remove 'e' once → {'e':1, 'c':1, 'b':1}
Shrink to "eb" → remove 'c' completely → {'e':1, 'b':1}
Window now valid again → maxLen remains 3
Continue to next char 'a' → invalid → shrink again...
Final result: 3
(substring "ece")
Edge Cases
s = ""
, k = 2
→ Output: 0
(empty input)
s = "a"
, k = 0
→ Output: 0
(k is 0, no characters allowed)
s = "abc"
, k = 3
→ Output: 3
(all characters fit)
s = "aaaa"
, k = 1
→ Output: 4
(only one character used)
Final Thoughts
This is a classic sliding window problem where we maintain a valid window using two pointers and a character frequency map. The key is to efficiently expand and contract the window so that it always satisfies the condition of having at most k
distinct characters.
With a good understanding of this problem, you'll build intuition for many real-world string-processing tasks and interview questions.
Comments
Loading comments...