Jump to section
- The Problem
- Start With the Brute Force
- The Optimal Approach: A Sliding Window
- Solution in Python and TypeScript
- Time and Space Complexity
- How to Talk Through Longest Substring Without Repeating Characters in an Interview
- Edge Cases and Common Follow-Ups
- Practise Longest Substring Without Repeating Characters in a Mock Coding Round
- FAQ
This problem asks for the length of the longest stretch of a string in which no character appears twice. The optimal solution is a sliding window: keep the last index where each character was seen, and when a repeat appears inside the window, move the window start just past it. It runs in O(n) time and O(k) space, where k is the size of the character set.
The Problem
You are given a string. Return the length of the longest substring that contains no repeated characters. A substring is a contiguous run of characters, so you cannot skip letters the way you could in a subsequence.
Example 1
Input: s = "abcabcbb"
Output: 3
Why: "abc" is the longest run with all different characters. Every longer run repeats a letter.
Example 2
Input: s = "pwwkew"
Output: 3
Why: "wke" works. "pwke" has the right letters but is not contiguous, so it does not count.
Assumptions to confirm
- Do you want the length or the substring itself? (Usually the length. Returning the substring needs only two extra variables.)
- Which characters can appear: letters only, or spaces, digits and symbols too? (Assume any character; a map handles all of them.)
- Is the comparison case-sensitive? (Assume yes, so "a" and "A" are different.)
- What should an empty string return? (0.)
Start With the Brute Force
The direct answer checks every substring and tests whether its characters are all different. There are about n²/2 substrings, and checking each one can take O(n), so this is O(n³) time. A smarter brute force grows each substring from a fixed start and stops at the first repeat, which brings it to O(n²).
Say this first, then point at the waste: when you find a repeat, you throw away the whole substring and start again one position later, even though almost all of it was valid. A window that keeps the valid part and only drops what it must is the improvement.
Ready to put this into practice?
Practice this with MockIF →Still applying for jobs? Let Auto Apply do it
The Optimal Approach: A Sliding Window
Keep a window [start, i] with no repeats
start is the left edge; i is the character you are adding now.
Remember where each character was last seen
A map from character to its latest index lets you find the repeat in constant time.
When the new character is already in the window, jump start
If its last index is at or after start, set start to that index plus one. Characters seen before start do not count, which is why the check compares with start.
Record the character and update the best length
Store the current index for the character, then compare i - start + 1 with the best so far.
Return the best length
Each character enters the window once and start only moves forward, so the work is linear.
Solution in Python and TypeScript
Both versions jump the window start directly to the right place instead of moving it one step at a time.
Python
def length_of_longest_substring(s: str) -> int:
last_seen: dict[str, int] = {} # char -> latest index
start = 0
best = 0
for i, ch in enumerate(s):
if ch in last_seen and last_seen[ch] >= start:
start = last_seen[ch] + 1 # jump past the repeat
last_seen[ch] = i
best = max(best, i - start + 1)
return best
TypeScript
function lengthOfLongestSubstring(s: string): number {
const lastSeen = new Map<string, number>(); // char -> latest index
let start = 0;
let best = 0;
for (let i = 0; i < s.length; i++) {
const prev = lastSeen.get(s[i]);
if (prev !== undefined && prev >= start) start = prev + 1; // jump past the repeat
lastSeen.set(s[i], i);
best = Math.max(best, i - start + 1);
}
return best;
}
The check last_seen[ch] >= start is the line most people get wrong. Take "abba": when the final "a" arrives, its last index is 0, but the window already starts at 2 after the second "b". Without the check, start would jump backwards to 1 and the answer would be wrong.
Ready to put this into practice?
Practice this with MockIF →Still applying for jobs? Let Auto Apply do it
Time and Space Complexity
| Approach | Time | Space | When to use it |
|---|---|---|---|
| Check every substring | O(nยณ) | O(k) | Only as your first spoken answer |
| Grow from each start | O(nยฒ) | O(k) | Short strings |
| Sliding window with a map | O(n) | O(k) | The expected interview answer |
How to Talk Through Longest Substring Without Repeating Characters in an Interview
A strong spoken answer follows the same five beats:
- Clarify: "Is it the length or the substring? Any characters, and is it case-sensitive?"
- Brute force: "I could try every substring, but when I hit a repeat I throw away work I have already done."
- Optimise: "I will keep a window with no repeats and a map of where I last saw each character. When a repeat lands inside the window, I move the start just past its previous position."
- Code: narrate the window check and why it compares the last index with start.
- Test: walk through "abcabcbb", then "abba" for the backwards-jump trap, then the empty string. State O(n) time and O(k) space.
Ready to put this into practice?
Practice this with MockIF →Still applying for jobs? Let Auto Apply do it
Edge Cases and Common Follow-Ups
The "abba" trap
Only move start forward. A repeat that sits before the current window must be ignored.
Return the substring itself
Keep the best start position alongside the best length, then slice at the end.
At most k distinct characters
A common follow-up. Keep counts in the map and shrink the window while there are more than k keys.
A small, fixed alphabet
For lowercase letters only, an array of 26 last-seen positions replaces the map and is slightly faster.
Unicode text
In some languages a single visible character can be two code units. Mention it if the interviewer asks about real-world text.
Practise Longest Substring Without Repeating Characters in a Mock Coding Round
Reading a solution is not the same as producing one with someone listening. The gap shows up as long silences, a jump straight to code without a brute force, or a bug you only spot after the interviewer asks you to test. The fix is to rehearse problems like Longest Substring Without Repeating Characters out loud, under time pressure, while explaining each decision.
MockIF runs mock coding interviews with a voice AI interviewer in a real in-browser editor, in Python and TypeScript. It runs your code against tests, asks you to explain your approach, adds follow-up questions the way a real interviewer would, and then scores your answer and gives specific feedback. Each session costs 2 credits. It is free to start with 5 credits, then monthly or 3-monthly plans, or one-off credit packs (see pricing).
Frequently Asked Questions
How do you solve longest substring without repeating characters in O(n)?
What is the sliding window technique?
Why compare the last-seen index with the window start?
Is this problem medium or hard?
What is the space complexity?
Stop Preparing in Your Head. Start Practicing Out Loud.
Drop your resume, add a job description, and get a mock interview like the real thing.
Start Free Mock Interview →Still applying for jobs? Let Auto Apply do it for you.