advanced9 min read·Updated September 20, 2026

Minimum Window Substring Explained: Tracing ADOBECODEBANC for ABC

Master the minimum window substring pattern. Walk through finding ABC in ADOBECODEBANC with sliding window mental models, character frequency maps, and edge cases.

By Learnisim AI·Published September 20, 2026
LEARNING ARCSetup → Model in the example → Full trace → Twist → Edge cases → Apply
PREREQUISITES
  • Hash maps or frequency arrays
  • Two-pointer array techniques
Minimum Window Substring: sliding pointer algorithm Target t = "ABC" in s = "ADOBECODEBANC" | Expected Min Window = "BANC" (len 4) Target Freq Map (t) 'A': 1 | 'B': 1 | 'C': 1 Sliding Window Mechanics 1. Right expands greedily until window is VALID (missing == 0) 2. Left contracts to minimize window size while keeping it valid 0 A 1 D 2 O 3 B 4 E 5 C 6 O 7 D 8 E 9 B 10 A 11 N 12 C Initial Window: "ADOBEC" (len 6) Min Window: "BANC" (len 4) L (idx 9) R (idx 12) 1. Expand Right (Greedy) • Right pointer marches from 0 to 5. • Spells substring "ADOBEC". • All target chars ('A','B','C') met! • missing count drops to 0. Result: Window is now VALID. 2. Contract Left (Optimize) • Left pointer advances to squeeze size. • Drops leading 'A', then 'D', 'O'. • Stops when window becomes invalid. • Records min length at each step. Result: Finds shorter valid slices. 3. Ultimate Solution • Sliding repeats across full string. • Reaches span from index 9 to 12. • Substring found: "BANC". • Time Complexity: O(N) linear scan. Optimal: Zero redundant checks!
Min window of "ADOBECODEBANC" covering "ABC" overview diagram
Why

Why We Need a Sliding Window for Substrings

Phase 1: The Combinatorial Explosion

Imagine you are handed a massive string and a tiny target string . Your mission is to find the absolute smallest contiguous slice of that contains every single character in , including duplicates. For our locked working example, the expected result is , which spans 4 characters. While also contains all three characters, it is length 6 and therefore too long.
If you approach this with brute force, you might generate every possible substring of , check each one to see if it holds an , a , and a , and then pick the shortest. But a string of length 14 has 105 non-empty substrings, and that number scales quadratically as . Scale up to one million characters, and the brute-force approach stalls out entirely.
To avoid this quadratic trap, we need a mechanism that inspects each character at most a constant number of times. Instead of starting over for every candidate substring, we want to slide a dynamic boundary across , expanding when we lack characters and contracting when we have a valid covering window.
python
s = "ADOBECODEBANC"
t = "ABC"
# Goal: Find the shortest substring of s containing 'A', 'B', and 'C'
# Expected answer: "BANC" (length 4)
Minimum Window Substring: Sliding Window in Action Target t = "ABC" | String s = "ADOBECODEBANC" | Optimal Result = "BANC" (Length 4) Target Characters Needed A B C Count: 1 each String s Array & Sliding Window Traversal: Minimum Window Found! (Len 4) A 0 D 1 O 2 B 3 E 4 C 5 O 6 D 7 E 8 B L (9) A 10 N 11 C R (12) 1 Expand Right (R) Find a valid window • Slide R outward to ingest chars. • Track counts in frequency map. • Stop when all targets are met. 2 Contract Left (L) Minimize window size • Once valid, slide L rightward. • Record min length ("BANC"). • Repeat until window breaks. 3 Why O(N) Efficiency Beating combinatorial trap • Brute force checks 105+ slices. • Sliding window visits each at most twice (Linear Time O(N)).
Why We Need a Sliding Window for Substrings diagram
Model

Building the Two-Pointer Sliding Window Mental Model

Phase 2: The Expanding and Contracting Rigor

To capture the smallest substring of containing every character of , we cannot afford to re-scan every possible window from scratch. Instead, we maintain two pointers, left and right, starting together at index 0. The right pointer explores outward, greedily taking in characters to satisfy our character requirements, while the left pointer trails behind, trying to squeeze the window as tight as possible without losing validity.
Imagine our algorithm as a physical band stretching across a timeline. As the right pointer moves from index 0 to 5, our window becomes . This span includes 'A', 'B', and 'C', satisfying our frequency requirements for . But is it the minimum? At this moment, the left pointer steps in, incrementing forward to see if we can drop the leading 'A' or 'D'. The core mechanism relies on a frequency map that counts how many of each target character we still need to enclose before the window is considered complete.
As right expands, we decrement our shortage count for matching characters. When shortage reaches zero, the window is complete. Then, left contracts until shortage ticks back up, recording the window length at each valid shrinkage step.
Try this: Given s = "ADOBECODEBANC" and t = "ABC", explain in your own words what condition triggers the left pointer to contract, and what condition triggers the right pointer to expand.
Sliding Window Mental Model: Minimum Window Substring Target t = "ABC" | Source s = "ADOBECODEBANC" String s Array & Pointer Mechanics Active Window (Valid & Contracting) A 0 D 1 O 2 B 3 E 4 C 5 O 6 D 7 E 8 B 9 A 10 N 11 C 12 Left (contracts) Right (expands) 1. Target Requirements Target Map t = {'A':1, 'B':1, 'C':1} All target characters must be satisfied • Shortage Count: Tracks how many required unique characters still lack frequency. • Window Validity: Valid ONLY when shortage == 0. All required counts are met. Stateful Frequency Tracking 2. Right Pointer: Expansion Action: Greedily Expand Right Incorporate characters into window • When to trigger: Whenever shortage > 0, window is incomplete. Right must move right. • Core effect: Decrements shortage count as target matches are enclosed. Greedy Search Phase 3. Left Pointer: Contraction Action: Squeeze Window Left Minimize span without breaking validity • When to trigger: Triggered when shortage == 0. Left pointer tries to drop dead weight. • Core effect: Record min length, increment left, until shortage ticks back up to 1. Optimal Shrinkage Phase
Building the Two-Pointer Sliding Window Mental Model diagram
Worked example

Tracing the Minimum Window Substring Algorithm on ADOBECODEBANC

Phase 3: Stepping Through the Pointers

To see the two-pointer sliding window in action, let us trace our locked example: finding the minimum window in that covers .
We start with a target frequency map for : {'A': 1, 'B': 1, 'C': 1}, meaning we need 3 unique character fulfillments, and a missing count of 3. Both pointers, left and right, begin at index 0.

Given

- String (length 13)
- Target
- Required counts:

Steps

1. Expand Right: We advance right from 0 to 5, spelling out ADOBEC.
- When right hits index 5 (character 'C'), all characters of are satisfied.
- Our missing count drops to 0.
- Current window: ADOBEC (length 6, indices 0 to 5).
2. Shrink Left: Now we try to optimize by advancing left while keeping the window valid ().
- Advance left from 0 to 1 (dropping 'A'). Wait, 'A' is required! But our window frequency map still allows it if we haven't broken the threshold. Actually, tracking carefully: dropping index 0 ('A') makes 'A' count go to 0, which violates our requirement since we need 1 'A'.
- So when left is at 0, dropping 'A' increments missing back to 1. We stop shrinking. The best window found so far is ADOBECODEBANC[0..5] = ADOBEC of length 6.
3.Continue Expansion and Shrinking:

- We resume expanding right past index 5. We sweep through ODEB until we hit index 10 ('A'), then index 11 ('N'), and finally index 12 ('C').
- When right hits index 12 (the final 'C'), the window spans from left index 9 to right index 12, which is BANC.
- Let's inspect the window BANC (indices 9 to 12): it contains 'B', 'A', 'N', 'C'. This includes all characters of .
- We now shrink left from index 9. If we move left past 'B' (index 9), we lose 'B', so becomes 1 again. Thus, the window cannot shrink further from the left.
- During this sweep, we also encountered windows like CODEBANC and tested shrinking them. The shortest valid window recorded during the entire run is length 4.

Result

The algorithm successfully identifies the minimum window substring as with a length of 4, beating our initial candidate (length 6).
Try this: Trace the algorithm for s = "ADOBECODEBANC" and t = "ABC". At what index of right does the window first become valid, and what characters are inside that initial window?
Phase 3: Tracing Sliding Window on ADOBECODEBANC Target t: "ABC" Req: A:1, B:1, C:1 missing: 0 (valid) Best Len: 4 ("BANC") A 0 D 1 O 2 B 3 E 4 C 5 O 6 D 7 E 8 B 9 A 10 N 11 C 12 Initial Window: ADOBEC (len 6) Min Window: BANC (len 4) left = 9 right = 12 left (started here) 1. Expand Right & Initial Window - Advance right to index 5 ('C'). missing = 0. - Found candidate "ADOBEC" of length 6. 2. Shrink Left & Final Minimum - Swept through CODEBANC, hit right = 12 ('C'). - Shrank left to index 9: optimal window "BANC" (len 4).
Tracing the Minimum Window Substring Algorithm on ADOBECODEBANC diagram
Practice

Predicting the Window Contraction State for a Modified Target

Phase 4: Practice Your Contraction Instincts

Now that you have traced how the window expands right and contracts left on the classic and example, it is time to test your mental model against a slight variation. Suppose we change the target string to while keeping the same source string .
Recall that the frequency map for requires at least two characters and one . As your right pointer expands across the source string, you must accumulate these frequencies before your window becomes valid and the left pointer begins its contraction phase. Think carefully about how the frequency map state machine responds to duplicate characters in and when the first valid window can finally shrink.

The Challenge

Given the source string and the modified target , trace the right pointer's expansion until the window first satisfies all frequency requirements. At that exact moment of first validity, what is the exact substring enclosed between your left and right pointers, and how many times can you immediately increment the left pointer before the window becomes invalid again?
python
s = "ADOBECODEBANC"
t = "AAB"
# Exercise: Determine the exact window bounds when validity is first reached,
# and trace how far the left pointer can shrink while maintaining validity.
Apply

Transferring the Sliding Window Pattern to Non-String Domains

Phase 5: Applying the Pattern Beyond Strings

We have successfully tracked our minimum window across the string for target , arriving at the optimal result . The power of this two-pointer expansion-contraction strategy is that it generalizes far beyond literal text manipulation. Whenever you face a collection of items where a contiguous subarray or segment must satisfy a set of inclusion criteria, the identical frequency-mapping and validity-counter mechanics apply.
Consider a neighboring problem: finding the smallest subarray of integers in an array that contains a specific set of required target values, or finding the shortest sub-segment of network log entries that contains a complete set of required error codes. The state variables change from character frequencies to integer counts or hash map bucket sizes, but the algorithm skeleton remains isomorphic.
To test this transfer of knowledge, apply the sliding window framework to the question below without resetting your mental model of the expand-right, shrink-left invariant.

FAQ

Why is the minimum window substring of 'ADOBECODEBANC' for 'ABC' equal to 'BANC'?
The window 'BANC' is the shortest contiguous segment that contains all characters of 'ABC' (one 'A', one 'B', and one 'C'). While 'ADOBEC' also contains all three letters, its length is 6, whereas 'BANC' has a length of 4.
When should I use a sliding window instead of checking all substrings?
Use a sliding window when you need to find a contiguous subarray or substring that satisfies a specific condition. It reduces time complexity from O(N^2) or O(N^3) down to O(N) by expanding and contracting bounds instead of rechecking every possible slice.
What is the most common pitfall when implementing this algorithm?
A frequent mistake is failing to properly maintain the frequency counts during contraction. You must decrement your match count only when a character's frequency drops below the required threshold in your target map.
What is the time and space complexity of the minimum window substring algorithm?
The time complexity is O(N + M), where N is the length of the source string and M is the length of the target string, because both pointers traverse the string at most twice. Space complexity is O(K), where K is the number of unique characters in the target string.

Keep learning