Find longest substring without repeating characters
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
The standard solution to the longest-substring-without-repeating-characters problem is a sliding window. The idea is to keep a window of unique characters, expand it as long as the next character is new, and shrink or jump the left side when a duplicate appears. That gives a linear-time solution instead of checking every possible substring.
Understand why brute force is too slow
A brute-force solution inspects every substring and checks whether it contains duplicates. That is easy to understand, but it becomes expensive quickly because there are many substrings and each duplicate check costs more work.
For interviews or production code, brute force is mainly useful as a correctness baseline, not as the final algorithm.
Solve it with a sliding window and last-seen positions
The efficient pattern stores the last index where each character appeared. When a duplicate appears inside the current window, move the left boundary just past the previous occurrence.
This runs in O(n) time because each index is processed once, and the left pointer never moves backward.
Why jumping the left pointer is better than deleting one by one
Some sliding-window solutions remove characters from a set one step at a time when a duplicate is found. That also works, but the last-seen-index approach is usually cleaner because it jumps directly to the right place.
Example with "abba":
- read
a, window isa - read
b, window isab - read second
b, moveleftfrom0to2 - continue with
a
The important detail is the condition last_seen[char] >= left. Without that guard, an old occurrence outside the current window could move left backward incorrectly.
Return the substring itself, not just the length
Sometimes the problem asks for the actual substring. Track the best start index while updating the best length.
That version is often more practical because users usually care about the substring, not only the number.
Edge cases to handle explicitly
The sliding window handles common edge cases naturally, but it is worth thinking through them:
- empty string should return
0or"" - repeated single character such as
"aaaa"should return1 - duplicates outside the current window must not force the left pointer backward
Testing these cases prevents subtle bugs in the update condition.
Character model considerations
In most interview settings, treating a Python string as a sequence of characters is enough. In production systems with Unicode-heavy text, the definition of a "character" can be more complicated because user-perceived characters may span multiple code points. The algorithmic idea stays the same, but the tokenization step may need to operate on grapheme clusters rather than raw code points.
That nuance matters mostly in internationalized text processing, not in the core interview problem.
Common Pitfalls
- Resetting the entire window when a duplicate appears instead of moving only the left boundary.
- Forgetting the
last_seen[char] >= leftcheck and moving the window backward incorrectly. - Returning the length when the caller actually needs the substring itself.
- Using brute force for large inputs when a linear sliding window is available.
- Missing empty-string and repeated-character edge cases in tests.
Summary
- Use a sliding window with last-seen character indices for the standard efficient solution.
- The algorithm runs in
O(n)time andO(k)space, wherekdepends on the character set used. - Move the left boundary only when the duplicate is inside the current window.
- Track the best start index as well if you need the substring itself.
- Test edge cases such as empty input and repeated characters to verify the window logic.

