Compile Ready
Module 3 · Variable Window

Minimum Window Substring

HardProblem 7 of 17 10 min read ~25 min to solve LeetCode
Sliding WindowTwo PointersHash MapStringFrequency Counting
Asked atAmazonGoogleMicrosoftMetaNetflixOracle

Problem Statement

Given two strings s and t, return the minimum-length substring of s that contains every character of t, including duplicate requirements. If no such substring exists, return an empty string.

Input

Two strings: s, the search text, and t, the multiset of required characters.

Output

The shortest contiguous substring of s that contains all characters from t with the required multiplicities, or an empty string if no such window exists.

Constraints

  • 1 <= s.length, t.length <= 10^5
  • s and t consist of uppercase and lowercase English letters
  • The answer is unique when it exists

Examples

Example 1

Input:
s = ADOBECODEBANC, t = ABC
Output: BANC
Explanation: **BANC** contains **A**, **B**, and **C**, and no shorter substring of **s** contains all three.

Example 2

Input:
s = a, t = a
Output: a
Explanation: The single character window satisfies the requirement.

Example 3

Input:
s = a, t = aa
Output:
Explanation: **s** contains only one **a**, but **t** requires two.

Learning Objectives

  • Model **t** as required character frequencies rather than a set.
  • Track how many distinct required characters are fully satisfied by the current window.
  • Use the shortest-valid template: expand until all requirements are met, then shrink to minimize.
  • Handle duplicate requirements and irrelevant characters without special cases.

Intuition

Pattern Identification

This is a shortest-valid variable-window problem. A window is valid when it covers the required multiset from t. Expanding right can only add coverage, while shrinking left may remove coverage. That creates the classic two-phase loop: grow until valid, then shrink while still valid to expose the minimum window.

The expand and shrink invariant is based on matched requirements. Maintain need counts from t, window counts from the current substring, and formed, the number of distinct required characters whose window count has reached the needed count. When formed equals the number of required distinct characters, the window is valid and should be minimized immediately.

Common mistakes

  • ×Treating **t** as a set and ignoring duplicate characters like **AA**.
  • ×Incrementing the matched count every time a required character appears, even after its needed count is already satisfied.
  • ×Shrinking before recording the current valid window.
  • ×Removing irrelevant characters incorrectly even though they should not affect **formed**.

Algorithm Explanation

Window setup

Build need counts for t using an ASCII table. Track required, the number of distinct characters with positive need. As the window moves over s, update window counts and maintain formed, the number of required characters whose current count is at least exactly satisfied.

Window visualization

For s = ADOBECODEBANC and t = ABC, the window first becomes valid at ADOBEC when it has A, B, and C. Record that length, then shrink from the left. Removing A breaks validity, so expansion resumes. Later, when the window reaches CODEBANC, all requirements are satisfied again. Shrinking removes irrelevant and extra characters until the compact valid window BANC remains. Removing B would break validity, so BANC is the minimum for that right boundary and becomes the final answer.

Algorithm

  1. Count required characters from t in need and compute required.
  2. Initialise left = 0, formed = 0, and best window metadata.
  3. Expand right through s, adding each character to window.
  4. When a required character count becomes exactly satisfied, increment formed.
  5. While formed == required, record the current window if it is shorter than the best.
  6. Remove s[left], decrement formed if that removal makes a required count fall below its need, then increment left.
  7. Return the best substring if one was recorded; otherwise return an empty string.

Solutions

Solution: Matched frequency sliding window

The window carries two count tables: what is needed from t and what is currently present. A distinct required character contributes to formed only when its count reaches the needed frequency, which handles duplicates naturally.

Step-by-step

  1. Build the need table and count how many distinct required characters exist.
  2. Expand the right boundary, updating the current window count.
  3. When a character reaches its required count, increment formed.
  4. While all requirements are formed, update the best answer and remove characters from the left.
  5. If removing a character drops it below its required count, the window becomes invalid and expansion resumes.
  6. Return the saved best substring, or an empty string if no valid window was found.
Time

O(n + m)

Space

O(1)

Here n is s.length and m is t.length. The two ASCII count tables have fixed size 128.

Java implementation

Loading…

Dry Run

Sample input

s = ADOBECODEBANC, t = ABC. Track distinct requirements satisfied and the best window after each important expansion or shrink.

stepright charleftwindow stateformed of requiredbest window
1A at 00A count satisfied1 of 3none
2B at 30A and B satisfied2 of 3none
3C at 50A, B, C satisfied in ADOBEC3 of 3ADOBEC
4shrink past A1A no longer satisfied2 of 3ADOBEC
5A at 101all requirements satisfied again in DOBECODEBA3 of 3ADOBEC
6shrink to C5CODEBA still valid before removing C3 of 3CODEBA
7C at 126ODEBANC valid, then shrink irrelevant chars3 of 3CODEBA
8shrink to BANC9BANC is valid and length 43 of 3BANC

The shortest valid window found is BANC. Shrinking stops there because removing B would make the window miss a required character.

Interview Tips

Emphasize that this is a multiset coverage problem, not a set membership problem. The clean explanation is required distinct characters versus formed distinct characters. Record the best window before each left removal, because the window is valid at the top of the shrink loop. Use arrays for ASCII constraints or maps for a larger character set.

Likely follow-ups

  • How would the solution change for full Unicode strings?
  • How would you return all minimum windows if multiple answers had the same length?
  • How would you handle a stream of characters where **s** is not fully stored?
  • How would you adapt the approach if each required character had a weight instead of a count?

Similar Problems

Key Takeaways

  • Minimum Window Substring is shortest-valid sliding window over required counts.
  • Use frequency counts, not sets, because duplicates in **t** matter.
  • **formed == required** is the signal to shrink and minimize.
  • Record the answer before removing from the left side of a valid window.
Reusable template: For minimum coverage windows, expand until every requirement is satisfied, then repeatedly record and shrink left until one requirement breaks.