Understanding the Problem
We are given two strings — a source string s
and a target string t
. Our goal is to find the smallest possible substring in s
that contains all the characters of t
, including their frequencies. For example, if t
contains 2 'A's, the window in s
must also have 2 'A's. The order of characters does not matter. If no such window exists, we return an empty string.
This is a classic use-case for the sliding window technique, where we dynamically expand and contract a range over the source string to track the minimal valid window.
Step-by-Step Solution with Example
Step 1: Build the frequency map for target string
Let’s take the example: s = "ADOBECODEBANC"
and t = "ABC"
.
We first count how many times each character appears in t
. This gives us a hash map:
{
A: 1,
B: 1,
C: 1
}
Step 2: Set up sliding window pointers and other variables
We initialize two pointers left
and right
at 0 to represent the window. We also maintain:
window
: a hash map to count character frequencies in the current window
valid
: how many characters from t
are satisfied in the current window
start
: the starting index of the smallest valid window found so far
minLen
: the length of that smallest valid window (initialized to infinity)
Step 3: Expand the window by moving right
We move the right
pointer one step at a time and update window
. If the character at s[right]
exists in need
and we now have the right frequency, we increment valid
.
Example:
- right=0 → 'A' → valid = 1
- right=3 → 'B' → valid = 2
- right=5 → 'C' → valid = 3
Now that valid === 3
, we know the window has all the needed characters.
Step 4: Try to shrink the window by moving left
We now move the left
pointer to reduce window size. At each step, we check if the window is still valid. If so, we update start
and minLen
if it’s the smallest window so far.
When we remove a character from the left and it drops below the required frequency in need
, we decrease valid
.
Step 5: Repeat until right reaches the end
We keep expanding with right
and shrinking with left
as long as possible. At the end, we return the smallest window found using s.substring(start, start + minLen)
.
Final Output for Example
For s = "ADOBECODEBANC"
and t = "ABC"
, the minimum valid window is "BANC"
.
Edge Cases
- Empty strings: If
s
or t
is empty, return ""
.
- No match: If
t
has characters not in s
, return ""
.
- Duplicate characters in t: Make sure to track correct frequencies. For example,
t = "AABC"
must be matched as A:2, B:1, C:1
.
- s == t: If both strings are equal and valid, return
s
.
Final Thoughts
This problem teaches how to effectively apply the sliding window + hash map pattern for substring problems involving character frequency constraints. It also emphasizes the importance of expanding and contracting the window at the right time to optimize for minimum length. By carefully maintaining the need
and window
maps, and tracking the valid
count, we ensure correctness even when there are duplicates or edge conditions.
This is a powerful pattern used in many substring problems such as anagrams, permutation match, and more.
Comments
Loading comments...