Given a string s
, find the length of the longest substring that contains at most two distinct characters.
Example 1:
Input: s = "eceba"
Output: 3
Explanation: The longest substring with at most two distinct characters is "ece", which has a length of 3.
Example 2:
Input: s = "ccaabbb"
Output: 5
Explanation: The longest substring with at most two distinct characters is "ccaab", which has a length of 5.
Clarifications:
Write a function that takes a string s
as input and returns the length of the longest substring with at most two distinct characters. The function should be optimized for performance. Consider edge cases such as empty strings or strings with only one or two distinct characters. Discuss time and space complexity.
When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
The brute force method for this problem means we will look at every single possible section (substring) of the given text. We will check each one to see if it follows the rule of having at most two different letters and keep track of the longest section we find that follows the rule.
Here's how the algorithm would work step-by-step:
def longest_substring_with_at_most_two_distinct_characters_brute_force(input_string):
longest_substring_length = 0
for starting_index in range(len(input_string)):
for ending_index in range(starting_index, len(input_string)):
substring = input_string[starting_index:ending_index + 1]
# This ensures that we're only looking at distinct letters within the current substring
distinct_characters = set(substring)
# We only care about substrings that satisfy the two distinct characters rule
if len(distinct_characters) <= 2:
current_substring_length = len(substring)
# Find out if our current substring is bigger than the currently known max
if current_substring_length > longest_substring_length:
longest_substring_length = current_substring_length
return longest_substring_length
We want to find the longest chunk of text that contains no more than two different letters. Instead of checking every possible chunk, we'll use a 'sliding window' approach, expanding and shrinking our view to efficiently find the best one.
Here's how the algorithm would work step-by-step:
def longest_substring_with_at_most_two_distinct_characters(input_string):
window_start = 0
max_length = 0
character_frequency = {}
for window_end in range(len(input_string)):
right_character = input_string[window_end]
if right_character not in character_frequency:
character_frequency[right_character] = 0
character_frequency[right_character] += 1
# Shrink the window until we have at most two distinct characters
while len(character_frequency) > 2:
left_character = input_string[window_start]
character_frequency[left_character] -= 1
# Clean up characters with 0 frequency to maintain accuracy
if character_frequency[left_character] == 0:
del character_frequency[left_character]
window_start += 1
# Update the max length if the current window is longer
current_window_length = window_end - window_start + 1
max_length = max(max_length, current_window_length)
return max_length
Case | How to Handle |
---|---|
Null or empty input string | Return 0, indicating an empty substring. |
String with only one distinct character | Return the length of the string, as the entire string is a valid substring. |
String with exactly two distinct characters repeated many times | Ensure the algorithm correctly identifies the entire string as the longest substring. |
Long string to check for performance issues | Sliding window approach is O(n) and handles large strings efficiently without excessive memory usage. |
String with more than two distinct characters, but a long substring with only two | The algorithm should correctly identify and return the longest substring adhering to the two distinct character constraint. |
Input string contains non-ASCII characters | The sliding window and character counting mechanism should work correctly with Unicode characters. |
String starting or ending with the same character | The sliding window correctly handles the start/end by expanding and contracting as required. |
String with all same characters | The entire string is a valid substring with at most two distinct characters and should be returned. |