Skip to content

Longest Substring Without Repeating Characters

Given a string s, find the length of the longest substring without repeating characters.

A substring is a contiguous sequence of characters within the string. You must return the length (integer), not the substring itself.

InputOutputExplanation
"abcabcbb"3The longest substring is "abc", which has length 3.
"bbbbb"1The longest substring is "b", which has length 1.
"pwwkew"3The longest substring is "wke" or "kew", which has length 3.
""0Empty string has no substring.
"au"2The longest substring is "au", which has length 2.
  • 0 <= s.length <= 5 * 10^4
  • s consists of English letters, digits, symbols, and spaces.
ApproachTimeSpaceReturnsBest When
Brute ForceO(n³)O(min(n, m))LengthString is tiny, practicing the concept, or interviewer explicitly requests it
Sliding WindowO(n)O(min(n, m))*LengthGeneral case — fast, clean, and efficient

* Space is proportional to the character set size, not string length. For English letters only, this is O(26) = O(1).

  • Pick Sliding Window if you want the best all-around interview answer.
  • Pick Brute Force if you are still learning how to think about substrings.
  • Every interviewer expects the sliding window solution for this problem.
Best For Speed
Sliding Window
O(n) time · O(min(n, m)) space
Learning Tool
Brute Force
O(n³) time · O(min(n, m)) space
Section titled “Approach 1: Sliding Window with Hash Map (Recommended)”
★ Recommended

Use two pointers (left and right) to maintain a window. Expand the window by moving right forward. When a character is seen that already exists in the current window, shrink the window from the left until the duplicate is removed.

The key insight is that each character is visited at most twice (once by right, once by left), making this a single linear pass through the string.

⏱ Time O(n) Each character visited once per pointer 💾 Space O(min(n, m)) Character set (max 26 letters or full Unicode)

Input: s = "abcabcbb"

Stepleftrightcharwindowseenmax_lengthAction
100’a’"a"{a:0}1Add ‘a’, expand
201’b’"ab"{a:0, b:1}2Add ‘b’, expand
302’c’"abc"{a:0, b:1, c:2}3Add ‘c’, expand
403’a’"bca"{b:1, c:2, a:3}3’a’ seen at 0, move left to 1, update ‘a’ to 3
514’b’"cab"{c:2, a:3, b:4}3’b’ seen at 1, move left to 2, update ‘b’ to 4
625’c’"abc"{a:3, b:4, c:5}3’c’ seen at 2, move left to 3, update ‘c’ to 5
736’b’"ab"{a:3, b:6, c:5}3’b’ seen at 4, move left to 5, update ‘b’ to 6
857’b’"b"{b:7, c:5}3’b’ seen at 6, move left to 7, update ‘b’ to 7

Animated walkthrough

How the sliding window finds the longest substring

Use Next or Autoplay to watch the window expand and contract as characters are processed. Notice how the left pointer jumps when a duplicate is found.

Step 1 of 8
Waiting to begin...
Array state
Memory / lookup state

function longestSubstringWithoutRepeatingCharactersSlidingWindow(s):
charIndex = {}
maxLength = 0
left = 0
for right from 0 to len(s) - 1:
if s[right] in charIndex and charIndex[s[right]] >= left:
left = charIndex[s[right]] + 1
charIndex[s[right]] = right
maxLength = max(maxLength, right - left + 1)
return maxLength
longest_substring_without_repeating_characters_sliding_window.py
def longest_substring_without_repeating_characters_sliding_window(s: str) -> int:
char_index = {}
max_length = 0
left = 0
for right in range(len(s)):
if s[right] in char_index and char_index[s[right]] >= left:
left = char_index[s[right]] + 1
char_index[s[right]] = right
max_length = max(max_length, right - left + 1)
return max_length
print(longest_substring_without_repeating_characters_sliding_window("abcabcbb")) # 3
✓ Simple

Check every possible substring and find the longest one without repeating characters.

For each starting position i, extend to position j and check if all characters from i to j are unique. Keep track of the maximum length found.

This approach is slow but instructive: it explicitly shows what a “valid substring” is.

⏱ Time O(n³) Three nested loops: i, j, and checking duplicates 💾 Space O(min(n, m)) Set for characters in current window

Input: s = "abcabcbb"

ijsubstringhas duplicate?actionmax_length
00”a”NoAdd to set, update max1
01”ab”NoAdd ‘b’, update max2
02”abc”NoAdd ‘c’, update max3
03”abca”Yes (‘a’)Break inner loop3
11”b”NoStart new substring3
12”bc”NoAdd ‘c’, max stays 33
13”bca”NoAdd ‘a’, max stays 33
14”bcab”Yes (‘b’)Break3
function longestSubstringWithoutRepeatingCharactersBruteForce(s):
maxLength = 0
for i from 0 to len(s) - 1:
charSet = {}
for j from i to len(s) - 1:
if s[j] in charSet:
break
charSet.add(s[j])
maxLength = max(maxLength, j - i + 1)
return maxLength
longest_substring_without_repeating_characters_brute_force.py
def longest_substring_without_repeating_characters_brute_force(s: str) -> int:
max_length = 0
for i in range(len(s)):
char_set = set()
for j in range(i, len(s)):
if s[j] in char_set:
break
char_set.add(s[j])
max_length = max(max_length, j - i + 1)
return max_length
print(longest_substring_without_repeating_characters_brute_force("abcabcbb")) # 3
✓ Simple

A third approach demonstrating an alternative technique for solving this problem. This implementation optimizes either time or space complexity compared to the previous approaches.

⏱ Time O(n) Optimized complexity 💾 Space O(1) Efficient space usage
function approach3():
// Implementation approach goes here
longest_substring_without_repeating_characters_optimized.py
"""
Solution for Longest Substring Without Repeating Characters
"""
def solve():
"""Implementation for approach 3 of Longest Substring Without Repeating Characters"""
pass
if __name__ == "__main__":
print("Solution ready")