Given a string s
, find the length of the longest substring without duplicate characters.
For example:
s = "abcabcbb"
. The answer is "abc", with the length of 3.s = "bbbbb"
. The answer is "b", with the length of 1.s = "pwwkew"
. The answer is "wke", with the length of 3. Note that the answer must be a substring, "pwke" is a subsequence and not a substring.What is the most efficient way to find the length of the longest substring without repeating characters? What is the time and space complexity of your approach? Can you provide code for your approach? Make sure to handle edge cases such as empty strings or strings with all repeating characters.
The most straightforward approach is to generate all possible substrings of the input string s
and then check each substring to see if it contains only unique characters. We keep track of the longest such substring found.
Algorithm:
n-1
, where n
is the length of s
).n-1
).Code (Python):
def length_of_longest_substring_brute_force(s):
n = len(s)
max_len = 0
for i in range(n):
for j in range(i, n):
substring = s[i:j+1]
if len(set(substring)) == len(substring):
max_len = max(max_len, len(substring))
return max_len
Time Complexity: O(n^3). The outer loops iterate in O(n^2) and the substring check takes O(n) in the worst case.
Space Complexity: O(n) in the worst case because set(substring)
can store up to n
characters.
A more efficient approach is to use the sliding window technique. We maintain a "window" defined by two pointers, left
and right
. We expand the window to the right until we find a duplicate character. When a duplicate is found, we shrink the window from the left until the duplicate is removed. We continuously update the maximum length of the substring without duplicate characters.
Algorithm:
left
and right
pointers to 0.set
(or hash map) to store the characters in the current window.right
is less than the length of the string.
right
is not in the set
, add it to the set
, increment right
, and update the maximum length.right
is already in the set
, remove the character at left
from the set
, and increment left
.Code (Python):
def length_of_longest_substring(s):
n = len(s)
left = 0
right = 0
max_len = 0
char_set = set()
while right < n:
if s[right] not in char_set:
char_set.add(s[right])
max_len = max(max_len, right - left + 1)
right += 1
else:
char_set.remove(s[left])
left += 1
return max_len
Time Complexity: O(n). Each pointer (left
and right
) moves at most n
steps.
Space Complexity: O(min(m, n)), where n is the length of the string and m is the size of the character set. In the worst case (all characters are unique), the space complexity is O(n). However, if the character set is small (e.g., ASCII), the space complexity is O(1).