Given two strings s and t, return the smallest substring of s that contains all
the characters in t (including duplicates). If no such string exists, return an
empty string "".
Example 1:
Input: s = "ADOBECODEBANC", t = "ABC"
Output: "BANC"
Example 2:
Input: s = "aaaabbbbbcdd", t = "abcdd"
Output: "abbbbbcdd"
Playground: Leetcode 76
General Observations
Below are a few key insights that will help us figure out a suitable algorithm to solve this problem:
Q1. How to check if a substring of s is a valid candidate?
We can maintain a frequency map of t. If a substring of s contains every character from
t with at least its required frequency, then the substring is a valid candidate.
Q2. Can there be multiple correct answers?
No, we can assume all test cases will have a unique answer.
Brute Force Approach - Nested Loops
Loop over each substring of s and keep track of the smallest substring that contains
all the required characters from t with at least the required frequencies.
Algorithm
1. Create a frequency map of all characters in "t".
2. Initialize variables to store the length and value of the smallest valid substring found so far.
3. Start from every character in "s" and expand the substring one character at a time.
4. Maintain a frequency map for the required characters present in the current substring.
5. After each expansion, check whether the current substring contains every character from "t"
with at least the required frequency.
6. If it is valid and shorter than the current minimum, update the answer.
7. After checking all possible substrings, return the smallest valid substring.
Implementation
Time Complexity
There are n(n+1)/2 possible substrings of s, so traversing all substrings contributes O(n²).
For each substring, we iterate over reqFreqMap to check whether every required character is present
with the required frequency. This takes O(k), where k is the number of distinct characters in t.
Hence, the overall time complexity will be O(n² · k).
Space Complexity
Both reqFreqMap and currFreqMap will store the frequency of all the distinct characters in t.
Assuming k is the number of distinct characters in t, the overall space complexity will be O(k).
Key Optimization
Once the current window [start, end] becomes valid, it contains all the characters present in t. We
can make a few observations to avoid performing unncessary work from the brute-force (nested-loop)
approach:
- No need to explore earlier ending positions: Since the previous window
[start, end-1]was invalid, any smaller window ending at or beforeend-1will also be invalid because it contains even fewer characters. Therefore, there is no need to explore those windows again.

- Shrink the current valid window: The current window may contain unnecessary characters at the
beginning. Therefore, we can increment
startto remove characters from the left and try to find a smaller valid window ending atend.

Sliding Window Approach
Use two pointers: [start, end] to maintain a sliding window containing the current substring. Move
end forward until the window becomes valid, then move start forward to make the valid window as
small as possible.
Algorithm
1. Create a frequency map of all characters in "t".
2. Initialize variables to store the length and value of the smallest valid substring found so far.
3. Initialize two pointers, "start" and "end", to represent the boundaries of the current sliding window.
4. Increment "end" to expand the window one character at a time and update the frequency of the
required characters in the current window.
5. For each expansion, check if the current window contains every character from "t" with at least
the required frequency.
6. While the current window is valid:
- Update the smallest valid substring is the current window is smaller.
- Increment "start" to shrink the window.
- If character removed from the window is required by "t", update its frequency in the current window.
7. Return the shortest valid substring.
Implementation
Time Complexity
Each character in s is processed at most twice: once when the end pointer expands the
window and once when the start pointer shrinks the window.
For each validity check, we iterate over all distinct characters in t, which takes O(k),
where k is the number of distinct characters in t.
Therefore, the overall time complexity is O(n · k).
Space Complexity
The overall auxiliary space complexity is the same as the brute-force approach, i.e., O(k),
where k is the number of distinct characters in t.