Longest Non-repeating SubstringLoading saved progress…

Longest Non-repeating Substring

Implement longestNonRepeatingSubstring(s). Given a string s, return the length (a number) of the longest contiguous substring of s that contains no duplicate characters. A substring is a contiguous slice of the original string — not a subsequence, which can skip characters. For "abcabcbb" the answer is 3 (the substring "abc"); for "bbbbb" it is 1 ("b"); for "pwwkew" it is 3 ("wke", not the 4-character subsequence "pwke").

This is the classic "longest substring without repeating characters" problem. The naive O(n²) solution is straightforward — and slow on long strings. The interesting work is doing it in O(n) with a sliding window plus a last-seen index map.

Signature

// s:        string  — any string (may be empty, may contain unicode)
// returns:  number  — length of the longest substring with no repeats
function longestNonRepeatingSubstring(s: string): number;

Examples

longestNonRepeatingSubstring('abcabcbb'); // → 3   ("abc")
longestNonRepeatingSubstring('bbbbb');    // → 1   ("b")
longestNonRepeatingSubstring('pwwkew');   // → 3   ("wke", NOT "pwke" — subsequence)
longestNonRepeatingSubstring('');         // → 0   (empty string)
longestNonRepeatingSubstring('z');        // → 1   (single char)
longestNonRepeatingSubstring('abcdef');   // → 6   (all unique → full length)
longestNonRepeatingSubstring('a b a b');  // → 3   (space counts as a character; e.g. "b a")
longestNonRepeatingSubstring('abc123abc');// → 6   ("abc123")

Notes

  • Return the length, not the substring. The function returns a number. If you also want the substring itself, that's an extension — see Going further in the solution.
  • Substring, not subsequence. The characters must be contiguous in s. "pwke" is a valid subsequence of "pwwkew" but not a substring; the correct substring answer is "wke" (length 3).
  • Every character counts. Spaces, punctuation, digits, and symbols are all treated as ordinary characters. "a b" has length 3 (a, space, b) and contains no duplicates.
  • Empty string returns 0, not undefined. A common bug is initialising max to undefined and short-circuiting on length 0.
  • Do not mutate the input. Strings are primitives in JS so you couldn't mutate them anyway — but don't return a wrapped object or reach for String.prototype mutators.
  • Don't worry about unicode characters above the Basic Multilingual Plane (emoji like "🙂" made of surrogate pairs). The tests stick to BMP characters; if you want to handle astral plane characters, see Gotchas in the solution.
Loading editor…