Longest Substring Without Repeating Characters | Hello Interview
Sliding Window
Longest Substring Without Repeating Characters
medium
DESCRIPTION (inspired by Leetcode.com)
Write a function to return the length of the longest substring in a provided string s where all characters in the substring are distinct.
Example 1: Input:
s = "eghghhgg"
Output:
3
The longest substring without repeating characters is "egh" with length of 3.
Example 2: Input:
s = "substring"
Output:
8
The answer is "ubstring" with length of 8.
💻 Desktop Required
The code editor works best on larger screens.
Explanation
This solution uses a variable-length sliding window to consider all substrings without repeating characters, and returns the length of the longest one at the end.
We represent the state of the current window with a dictionary state which maps each character to the number of times it appears in the window.
def longestSubstringWithoutRepeat(s):
state = {}
max_length = 0
start = 0
for end in range(len(s)):
state[s[end]] = state.get(s[end], 0) + 1
while state[s[end]] > 1:
state[s[start]] -= 1
start += 1
max_length = max(max_length, end - start + 1)
return max_length
Alternate (Faster) Solution
An slightly more optimized solution represents the state of each window with a dictionary mapping each character to the index at which it last appeared in the window.
Each time we increment end to expand the window, we first check if the character at end is a duplicate by checking if s[end] is in the dictionary. If it is, we can contract the window until it is valid again by setting start to max(start, last_index + 1) where last_index is the previous appearance of s[end]. We use max() to ensure start never moves backward (the previous occurrence might be before the current window). This is faster because we can contract the window in one operation instead of using a while-loop to do it incrementally.
def longestSubstringWithoutRepeat(s):
state = {}
start = 0
max_length = 0
for end in range(len(s)):
if s[end] in state:
start = max(start, state[s[end]] + 1)
state[s[end]] = end
max_length = max(max_length, end - start + 1)
return max_length
Solution
def longestSubstringWithoutRepeat(s):
state = {}
max_length = 0
start = 0
for end in range(len(s)):
state[s[end]] = state.get(s[end], 0) + 1
while state[s[end]] > 1:
state[s[start]] -= 1
start += 1
max_length = max(max_length, end - start + 1)
return max_length