datarekha
Coding Patterns Medium Asked at AmazonAsked at GoogleAsked at Meta

Find the length of the longest substring without repeating characters.

The short answer

Use a variable-size sliding window with a hash map that records the most recent index of each character. When the right pointer hits a character already in the window, jump the left pointer to one past that character's last position — skipping over the repeat in one move rather than crawling one step at a time.

How to think about it

When a string question asks for the longest (or shortest) stretch that satisfies some rule, the interviewer is fishing for a sliding window. The brute force — generate every substring and check each for repeats — is O(n²) substrings times an O(n) scan, hopelessly cubic. The window collapses all of that into a single walk across the string, and the thing they want to see is whether you can keep that window valid without ever scanning backward.

Picture a window [left, right] that always holds distinct characters. You push right forward one character at a time. The instant s[right] is a character already inside the window, you have to evict the old copy — but you don’t crawl left forward one step at a time hunting for it. You stored its index in a hash map, so you teleport left straight to one position past it. The window is clean again in a single move, and you never re-read a character. The one piece of bookkeeping is the guard: only jump if the stored index is actually inside the current window, because the map keeps old entries around even after left has moved past them.

A worked example

def length_of_longest_substring(s):
    seen = {}        # char -> most recent index
    left = 0
    best = 0
    for right, ch in enumerate(s):
        # jump left only if the repeat sits inside the current window
        if ch in seen and seen[ch] >= left:
            left = seen[ch] + 1
        seen[ch] = right
        best = max(best, right - left + 1)
    return best

print(length_of_longest_substring("abcabcbb"))  # "abc"
print(length_of_longest_substring("bbbbb"))      # "b"
print(length_of_longest_substring("pwwkew"))     # "wke"
print(length_of_longest_substring(""))           # empty string
3
1
3
0

In "abcabcbb" the window grows to "abc", then every following character is a repeat, so left keeps jumping forward and the window never gets past length 3. "bbbbb" is all one letter — each new b shoves left right behind right, leaving a window of 1. "pwwkew" peaks at "wke", not "pwwke", because the second w resets the window. The empty string never enters the loop, so best stays 0.

Keep practising

All Coding Patterns questions

Explore further

Skip to content