Know this before you start: “Variable windows (grow until invalid, then shrink)”
Variable-size sliding windows
Grow the window on the right every step; whenever it breaks the rule, shrink it from the left until it's valid again. Track the best valid window.
The idea
For “longest / shortest stretch that satisfies a rule”, keep a window [left, right]. Move RIGHT forward one step at a time to include more.
If the window now breaks the rule (a repeated letter, too many zeros, sum too big), move LEFT forward until it's valid again. After each step, the window is the best one ending at RIGHT.
Each pointer only moves forward, at most n times each, so the total work is O(n).
See it step by step
Longest stretch without repeating letters in “abcabcbb”
- Grow: a, ab, abc (length 3).
- Add 'a': repeat. Shrink from the left past the old 'a' → bca.
- Add 'b': repeat → shrink → cab. Add 'c' → abc… the best stays 3.
In code (Python)
def longest_without_repeats(s):
seen = set()
left = best = 0
for right, ch in enumerate(s):
while ch in seen: # invalid: shrink from the left
seen.remove(s[left])
left += 1
seen.add(ch)
best = max(best, right - left + 1)
return best
print(longest_without_repeats("abcabcbb")) # 3
print(longest_without_repeats("pwwkew")) # 3O(n) time; space for what the window tracks.
When you'll use it
- “longest / shortest / minimum window” with a condition on what's inside: no repeats, at most k distinct, sum ≥ target.
Common mistakes
- Moving left backwards.
- Checking the answer while the window is still invalid.