Browse curriculum

Longest Substring Without Repeating Characters

Find the length of the longest substring without repeating characters.

Examples

Input:s = "abcabcbb"
Output:3
Explain:

"abc" is the longest stretch with no repeated character, so the answer is 3.

Input:s = "bbbbb"
Output:1
Explain:

Every character is "b", so no stretch longer than 1 avoids a repeat.

Input:s = "pwwkew"
Output:3
Explain:

"wke" is the longest repeat-free stretch, length 3. "pwke" does not count: its letters are not contiguous in the input, so it is a subsequence rather than a substring.

Problem Understanding

We need to find the length of the longest substring in a given string s that contains no duplicate characters.

A substring is a contiguous sequence of characters. For example, in "abcabcbb", "abc" is a substring, but "acb" is not (it skips characters).

Algorithm Strategy

We use the Sliding Window technique with a Hash Map (or Array for fixed charsets) to track characters in the current window.

  1. Initialize left = 0 and max_len = 0.
  2. Use a map to store the most recent index of each character.
  3. Iterate right from 0 to end of string:
    • If s[right] is in map and its index is >= left, it means we found a repeat inside our current window. Move left to map[s[right]] + 1 to skip the previous occurrence.
    • Update map[s[right]] to the current right index.
    • Update max_len = max(max_len, right - left + 1).
  4. Return max_len.

Key Insight: Instead of shrinking the window one character at a time, we can jump the left pointer directly past the duplicate. Both versions are O(N); the jump just skips the inner shrinking loop.

Interactive Visualization

"dvdf"

EMPTY WINDOW

d

0

v

1

d

2

f

3

left

0

right

—

Length

—

Best

0

map (char:last index)

Empty

 

left starts at 0, the map is empty and the best length is 0

Next

Read 'd' at 0

String

Legend & Complexity

Solid frame: the window between L and R

Dashed frame: the character just read repeats inside it

The earlier copy that left jumps past

Characters before L

d:0

A map entry before L: still stored, no longer counts

Time

O(n)

Space

O(min(n, charset))

Watch how the window expands and jumps the left pointer when a duplicate is found.

Dry Run: s = "dvdf"

Step Window Char Map State Action
1 "" d {} New char. Add 'd'. Window: "d". Max=1.
2 "d" v {d:0} New char. Add 'v'. Window: "dv". Max=2.
3 "dv" d {d:0, v:1} Duplicate 'd'! Old 'd' at idx 0. Move Left to 0+1=1. Update 'd' idx to 2. Window: "vd".
4 "vd" f {d:2, v:1} New char. Add 'f'. Window: "vdf". Max=3.
End Result: 3

Edge Cases & Common Mistakes

Edge Cases:

  • Empty String: Return 0.
  • Single Character: Return 1.
  • All Duplicates: "aaaa" -> Return 1.
  • No Duplicates: "abcdef" -> Return length of string.

Common Mistakes:

  • Not checking if duplicate is in active window: You might see a char that appeared way before left. Ensure map[char] >= left before moving left.
  • Subsequence vs Substring: Confusing contiguous substring with non-contiguous subsequence.

Solution

Optimized Sliding Window using a Hash Map for O(1) lookups.

Longest Substring Without Repeating Characters Code
1/**
2 * @param {string} s
3 * @return {number}
4 */
5var lengthOfLongestSubstring = function(s) {
6 let seen = new Map();
7 let left = 0;
8 let maxLen = 0;
9
10 for (let right = 0; right < s.length; right++) {
11 let char = s[right];
12 if (seen.has(char) && seen.get(char) >= left) {
13 left = seen.get(char) + 1;
14 }
15 seen.set(char, right);
16 maxLen = Math.max(maxLen, right - left + 1);
17 }
18 return maxLen;
19};

The approach, step by step

  1. Read the next character

    Move right forward and look up the character’s last index.

  2. Jump past a repeat

    If that index is at or after left, set left to one past it.

  3. Record and measure

    Store the character’s index and update the best length with right - left + 1.

Frequently asked questions

How does the sliding window solve Longest Substring Without Repeating Characters?

Keep a window [left, right] with no repeats and a map of each character’s last index. When the character at right was last seen inside the window, move left to one past that index; the window length updates the answer at every step.


Why check that the last index is at or after left?

The map keeps indices of characters that have already left the window. A repeat only matters if its earlier copy is still inside the window; jumping left backwards to an old index would reintroduce duplicates.


What is the time and space complexity?

O(n) time, since each character is read once, and O(min(n, charset)) space for the map of last indices.

Applying for software engineering roles? Free, no sign-up:

AI resume checker — match your resume to the job description