Sliding Window

A sliding window grows on the right and shrinks on the left, so each element enters and leaves once instead of being scanned again.

Longest substring without a repeated character

StopSliding window
s
  1. La0
  2. b1
  3. c2
  4. a3
  5. b4
  6. c5
  7. b6
  8. b7
length0best0
  • CH1 left
  • CH2 right
left = 0, best = 0, and last_index is empty.

When to reach for it

  • The question is about a contiguous run: a substring or a subarray.
  • You want the longest, shortest or best run that follows a rule.
  • Adding or dropping one element updates the rule cheaply: a count, a sum, a last-seen index.
  • The brute force rescans ranges that overlap.

What stays true

Right adds one character. If that makes a repeat, left jumps past the earlier copy before anything is measured. So every length the stage reads is a valid window's.

The window is always valid

StopSliding window
InvariantThe window never holds a repeated character.✓ Holds
  1. Lp0
  2. w1
  3. w2
  4. k3
  5. e4
  6. w5
length0best0
  • CH1 left
  • CH2 right
left = 0, best = 0, and last_index is empty.

Break it

Each input here has tripped up a version of this code. The stage runs the one that gets it right.

The last 'a' was seen at 0, before left. Jumping left to 1 would move it backwards and let 'bb' back in. It jumps only for a sighting inside the window.

Longest substring on the inputs that trip it up

StopSliding window
  1. La0
  2. b1
  3. b2
  4. a3
length0best0
  • CH1 left
  • CH2 right
left = 0, best = 0, and last_index is empty.
Answer2Steps11

Variants

Best time to buy and sell

StopSliding window
  1. 70
  2. B11
  3. 52
  4. 33
  5. 64
  6. S45
min_price1best_profit5
  • CH1 buy
  • CH2 sell
8/8

The window runs from buy day to sell day. Buy moves to any cheaper day.

Step through it →

Character replacement

StopSliding window
  1. A0
  2. A1
  3. B2
  4. LA3
  5. B4
  6. B5
  7. RA6

counts

  • A2
  • B2
k1maxFreq3length4best4
  • CH1 left
  • CH2 right
12/12

The window never shrinks. It slides when more than k letters would need changing.

Step through it →

Minimum window substring

StopSliding window
  1. A0
  2. B1
  3. A2
  4. A3
  5. LC4
  6. B5
  7. A6
  8. RB7

have / need

  • A1/2
  • B2/1
missing1best"ABA"
  • CH1 left
  • CH2 right
18/18

Grow until the window covers t, then shrink while it still does.

Step through it →

The code

The same algorithm in plain Python. The lit line is the one the current frame came from.

Longest substring without a repeated character

StopSliding window
  1. La0
  2. b1
  3. c2
  4. a3
  5. b4
  6. c5
  7. b6
  8. b7
length0best0
  • CH1 left
  • CH2 right
left = 0, best = 0, and last_index is empty.
longest_unique_substring.py
def length_of_longest_substring(s):    left = 0    best = 0    last_index = {}    for right in range(len(s)):        c = s[right]        if c in last_index and last_index[c] >= left:            left = last_index[c] + 1        last_index[c] = right        best = max(best, right - left + 1)    return best

Drill it