Skip to main content

3. Longest Substring Without Repeating Characters

mediumAsked at Twilio

Twilio's classic sliding-window question: given a string, return the length of the longest substring without repeating characters. The grading rubric weighs whether you build the optimal O(n) sliding window with a hash map, not the O(n^2) brute-force scan.

By Alex Chen, Founder, InterviewChamp.AI · Last verified

Source citations

Public interview reports confirming this problem appears in Twilio loops.

  • Glassdoor (2026-Q1)Recurring in Twilio backend on-site rounds, especially for SDK-engineering teams.
  • LeetCode Discuss (2025-12)Cited in Twilio coding-round reports as a 25-minute window-mechanics question.

Problem

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

Constraints

  • 0 <= s.length <= 5 * 10^4
  • s consists of English letters, digits, symbols and spaces.

Examples

Example 1

Input
s = "abcabcbb"
Output
3

Explanation: The answer is "abc", with the length of 3.

Example 2

Input
s = "bbbbb"
Output
1

Explanation: The answer is "b", with the length of 1.

Example 3

Input
s = "pwwkew"
Output
3

Explanation: The answer is "wke". Note that 'pwke' is a subsequence, not a substring.

Approaches

1. Brute-force — check every substring

Enumerate every (i, j) substring and verify uniqueness with a Set.

Time
O(n^3)
Space
O(min(n, alphabet))
function lengthOfLongestSubstringBrute(s) {
  const hasUnique = (str) => {
    const seen = new Set();
    for (const ch of str) {
      if (seen.has(ch)) return false;
      seen.add(ch);
    }
    return true;
  };
  let best = 0;
  for (let i = 0; i < s.length; i++) {
    for (let j = i + 1; j <= s.length; j++) {
      if (hasUnique(s.slice(i, j))) best = Math.max(best, j - i);
    }
  }
  return best;
}

Tradeoff: Conceptually trivial but O(n^3) — at the upper-bound 50k input it would time out in any interview environment. Twilio interviewers want to hear you name this then immediately move to the window approach.

2. Sliding window with hash map (optimal)

Maintain a window [left, right] where every character is unique. When a duplicate enters at right, jump left past the previous occurrence.

Time
O(n)
Space
O(min(n, alphabet))
function lengthOfLongestSubstring(s) {
  const lastIndex = new Map();
  let left = 0, best = 0;
  for (let right = 0; right < s.length; right++) {
    const ch = s[right];
    if (lastIndex.has(ch) && lastIndex.get(ch) >= left) {
      left = lastIndex.get(ch) + 1;
    }
    lastIndex.set(ch, right);
    best = Math.max(best, right - left + 1);
  }
  return best;
}

Tradeoff: Single pass over s. The 'lastIndex.get(ch) >= left' guard is the subtle bit — without it, a duplicate that was already evicted from the window would incorrectly move left backwards.

Twilio-specific tips

Twilio reviewers grade two things: (1) you propose the brute-force out loud, (2) the window code handles the 'duplicate but already evicted' case correctly. The most common rejection signal is candidates who jump straight to the optimal but write `left = lastIndex.get(ch) + 1` without the lower-bound guard — it silently produces wrong answers on inputs like 'abba'. Walk through that example before committing the code.

Common mistakes

  • Moving left without checking that the duplicate is still inside the current window — silently fails on 'abba'.
  • Using a Set and shrinking from the left one character at a time (correct but O(n) amortized work per character on adversarial inputs).
  • Counting substring length as right - left instead of right - left + 1.

Follow-up questions

An interviewer at Twilio may pivot to one of these next:

  • What if you needed at most K distinct characters instead of zero duplicates? (Same window, different invariant — see LC 340.)
  • What if the string was a stream you could not seek? (Same algorithm, you just process characters as they arrive.)
  • How would you adapt the answer to return the substring itself, not just its length?

Solve it now

Free. No sign-up. Python and JavaScript run instantly in your browser.

Output

Press Run or Cmd+Enter to execute

FAQ

Why is the guard `lastIndex.get(ch) >= left` necessary?

Because the map remembers every character ever seen, not just those in the current window. Without the guard, on input 'abba' the second 'a' would set left back to 1 even though the previous 'a' is already to the left of the current window, breaking correctness.

What's the worst-case space complexity?

O(min(n, alphabet)). If the alphabet is fixed (ASCII, 128 chars), space is bounded by 128 regardless of n. If the alphabet is unbounded (Unicode), it's O(n).

Free learning resources

Curated free links for this problem.

Practice these live with InterviewChamp.AI

Drill Longest Substring Without Repeating Characters and other Twilio interview questions under real-loop conditions with instant feedback on your reasoning, complexity claims, and code.

Practice these live with InterviewChamp.AI →