Files
leetcode/docs/(algorithms)/04-sliding-window.mdx
T

118 lines
3.4 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
title: 'Sliding Window'
description: 'Two pointers plus incremental state between them.'
---
## The idea
Two pointers that move the **same direction**, carrying state between them.
Think of a caterpillar:
- The head crawls forward and eats (expand right).
- When the rule breaks, the tail pulls in until the rule holds again (contract left).
The window is always a **contiguous** slice. You never rebuild it — you update the carried state as edges move. That is what makes it O(n).
**The recipe:**
1. Expand right. Add the new element to your state.
2. Rule broken? Contract left until it holds.
3. Record the best window. Repeat.
## The picture
```mermaid
flowchart TD
A["a b c a b c<br/>[a] window = a"] --> B["[a b] expand → ab"]
B --> C["[a b c] expand → abc, best = 3"]
C --> D["a [b c a] 'a' repeats → contract, then expand"]
D --> E["a b [c a b] keep sliding, best stays 3"]
style C fill:#2e7d32,color:#fff
```
## Longest Substring Without Repeating (LC 3)
State = a set of chars in the window. Repeat found? Shrink from the left until it is gone.
```python
def length_of_longest_substring(s: str) -> int:
window = set()
left = 0
best = 0
for right, c in enumerate(s):
while c in window: # rule broken
window.remove(s[left]) # contract left
left += 1
window.add(c) # expand right
best = max(best, right - left + 1)
return best
```
## Best Time to Buy and Sell (LC 121) — the hidden window
Looks like a stock problem. It is a window problem.
Left = cheapest buy so far. Right = today. Carry one number: the min price.
```python
def max_profit(prices: list[int]) -> int:
min_price = prices[0]
best = 0
for p in prices[1:]:
best = max(best, p - min_price)
min_price = min(min_price, p)
return best
```
## Character Replacement (LC 424) — window with a budget
Rule: window is valid if `window size count of top letter ≤ k`.
That many replacements fix the window. Carry a frequency map.
```python
from collections import defaultdict
def character_replacement(s: str, k: int) -> int:
count = defaultdict(int)
left = 0
best = 0
top = 0 # highest letter count seen
for right, c in enumerate(s):
count[c] += 1
top = max(top, count[c])
if (right - left + 1) - top > k: # over budget
count[s[left]] -= 1 # contract exactly one step
left += 1
best = max(best, right - left + 1)
return best
```
## When the window fails
Sliding window needs a one-way rule: **growing can only hurt, shrinking can only help.**
Negative numbers break this — a bigger window can flip from bad to good.
That is when you reach for prefix sum + hashmap (LC 560) instead.
Say this decision out loud in the interview.
## Complexity
| | Time | Space |
|---|---|---|
| All patterns above | O(n) — each index enters and leaves once | O(1) or O(alphabet) |
## Close-out ritual
Before you submit, say out loud:
1. Time and space complexity — note each element enters and leaves the window at most once.
2. One edge case trace: empty string, all same char, or k larger than the string.
## Plan problems
**A-set:** LC 121 · 3 · 424 · 567 · 76
**B-set:** LC 209 · 1004 · 643
<YouTube id="QGNAVBn1_bc" title="Sliding Window" />