Skip to main content

3. Longest Substring Without Repeating Characters

mediumAsked at Cohere

Find the length of the longest substring with all unique characters. Cohere asks this because sliding-window deduplication is core to tokenization span selection and context-window management in production language-model serving.

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

Source citations

Public interview reports confirming this problem appears in Cohere loops.

  • Glassdoor (2026-Q1)Cohere SWE and MLE candidates report this as one of the most common medium questions across all interview rounds.
  • Blind (2025-11)Consistently appears in Cohere interview prep threads as a must-solve sliding window problem.

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: "abc" has length 3.

Example 2

Input
s = "bbbbb"
Output
1

Explanation: "b" is the longest unique substring.

Example 3

Input
s = "pwwkew"
Output
3

Explanation: "wke" has length 3.

Approaches

1. Sliding window with Map

Use a Map to store the most recent index of each character. When a repeat is found, jump the left pointer past the previous occurrence. Update the max length on every iteration.

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

Tradeoff: O(n) single pass. The Map jump avoids redundant left-pointer increments and makes this faster than a Set-based shrink loop for long inputs.

2. Sliding window with Set

Maintain a Set of characters in the current window. When a repeat is encountered, shrink the window from the left until the repeat is removed.

Time
O(n)
Space
O(min(n, alphabet))
function lengthOfLongestSubstring(s) {
  const seen = new Set();
  let left = 0, maxLen = 0;
  for (let right = 0; right < s.length; right++) {
    while (seen.has(s[right])) {
      seen.delete(s[left++]);
    }
    seen.add(s[right]);
    maxLen = Math.max(maxLen, right - left + 1);
  }
  return maxLen;
}

Tradeoff: Simpler to reason about but the inner while loop makes it technically O(2n) in the worst case. Still O(n) overall, but the Map-jump approach avoids redundant iterations.

Cohere-specific tips

Cohere engineers regularly think about efficient windowing over token sequences. Frame the solution in terms of a streaming context window: 'My left and right pointers define the active context; on a collision I advance the left boundary to just after the previous occurrence — this models how a decoder discards stale context.' The Map-jump approach is preferred at Cohere because it avoids redundant deletions when handling large character spaces (e.g., Unicode).

Common mistakes

  • Forgetting the guard lastSeen.get(ch) >= left — without it, stale Map entries from outside the window trigger incorrect left-pointer jumps.
  • Returning right - left instead of right - left + 1 — off-by-one in window length calculation.
  • Updating maxLen only when a new character is added, not on every iteration.
  • Using string slicing to check uniqueness — O(n²) with extra allocations.

Follow-up questions

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

  • Longest Substring with At Most K Distinct Characters — extend the Map to count occurrences.
  • Minimum Window Substring — find the smallest window containing all target characters.
  • How would you track the longest unique-character span in a real-time token stream?

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 check lastSeen.get(ch) >= left?

Stale Map entries remain after the left pointer advances. Without the check, a character last seen before the current window would incorrectly trigger a left-pointer jump.

What is the alphabet size in the worst case?

For ASCII it is 128; for Unicode it can be much larger. Space complexity is O(min(n, |alphabet|)) — bounded by whichever is smaller.

Which approach should I code first?

The Map-jump approach — it is strictly more efficient and demonstrates a deeper understanding of why the Set approach does redundant work.

Practice these live with InterviewChamp.AI

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

Practice these live with InterviewChamp.AI →