Example 1
ready- Input
s = "abcabcbb"- Expected
3- Why
- 'abc' is the longest stretch with no repeated character
A repeated character can erase a promising streak in one step. Your job is to keep the longest streak alive.
Given a string s, return the length of its longest substring — a contiguous stretch
of characters — in which every character is different. The substring may contain
letters, digits, spaces, or symbols. If s is empty, return 0.
A few ground rules:
A and a are different.0 <= s.length <= 100_000s consists of printable ASCII: the basic letters, digits, symbols, and space.Hints
Fix a starting position and extend right until the next character is already in your set. That gives the best duplicate-free substring for that start. What work gets repeated when you move the start one step?
Track a window whose characters are all different. When the new rightmost character repeats, move the left edge past its previous copy.
Store character → latest index. A repeat may sit outside the current window, so
move left forward only when that saved index is at least left.
Could you return the substring as well without changing the O(n) running time?
Visible cases
s = "abcabcbb"3s = "bbbbb"1s = "pwwkew"3Interview signal
Pick each possible starting position and grow a set to the right. The first repeated
character ends that attempt: every longer substring from the same start still contains
the duplicate. An early cutoff also stops once the remaining suffix can't beat best.
def length_of_longest_substring(s: str) -> int:
best = 0
for start in range(len(s)):
if len(s) - start <= best:
break
seen: set[str] = set()
for end in range(start, len(s)):
if s[end] in seen:
break
seen.add(s[end])
best = max(best, end - start + 1)
return bestHere Σ is the alphabet size — the number of different characters the input may
use. Time O(n²), Space O(Σ) in the general case.
A sliding window is a contiguous range whose edges move while you scan. Keep the
window s[left:right + 1] duplicate-free. For each new character, its last saved index
tells you whether it already lives inside that window.
If it does, jump left one position past that copy. Use max so an older copy outside
the window never drags left backwards.
def length_of_longest_substring(s: str) -> int:
last_seen: dict[str, int] = {}
left = 0
best = 0
for right, char in enumerate(s):
if char in last_seen:
left = max(left, last_seen[char] + 1)
last_seen[char] = right
best = max(best, right - left + 1)
return bestEach character enters the scan once, and left only moves forward. Time O(n),
Space O(Σ) for the last-seen map. Printable ASCII fixes Σ at 95, but naming it keeps
the reasoning useful for larger alphabets too.
Ready to run.
3 cases are queued.
Visible testcase
Case 1
Expected
3