Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
Program to find the length of longest substring which has two distinct elements in Python
Suppose we have a string s, we have to find the length of the longest substring that contains at most 2 distinct characters.
So, if the input is like s = "xyzzy", then the output will be 4, as "yzzy" is the longest substring with at most 2 unique characters.
Algorithm
To solve this problem, we will use the sliding window technique with the following steps ?
Initialize start pointer to 0
Create a character frequency counter
Initialize answer to 0
-
For each character at the end pointer:
Add character to the counter
-
While we have more than 2 distinct characters:
Decrease count of character at start
If count becomes 0, remove from counter
Move start pointer forward
Update answer with maximum substring length
Implementation
from collections import Counter
def longest_substring_two_distinct(s):
if len(s) < 2:
return len(s)
start = 0
char_count = Counter()
max_length = 0
for end in range(len(s)):
# Add current character to counter
char_count[s[end]] += 1
# Shrink window if more than 2 distinct characters
while len(char_count) > 2:
char_count[s[start]] -= 1
if char_count[s[start]] == 0:
del char_count[s[start]]
start += 1
# Update maximum length
max_length = max(max_length, end - start + 1)
return max_length
# Test the function
s = "xyzzy"
result = longest_substring_two_distinct(s)
print(f"Input: {s}")
print(f"Length of longest substring with at most 2 distinct characters: {result}")
Input: xyzzy Length of longest substring with at most 2 distinct characters: 4
How It Works
For the string "xyzzy", let's trace through the algorithm:
def trace_algorithm(s):
start = 0
char_count = Counter()
max_length = 0
print(f"Processing string: {s}")
print("Step | Char | Window | Distinct | Max Length")
print("-" * 45)
for end in range(len(s)):
char_count[s[end]] += 1
# Shrink window if needed
while len(char_count) > 2:
char_count[s[start]] -= 1
if char_count[s[start]] == 0:
del char_count[s[start]]
start += 1
current_window = s[start:end+1]
max_length = max(max_length, end - start + 1)
print(f"{end+1:4d} | {s[end]:4s} | {current_window:6s} | {len(char_count):8d} | {max_length:10d}")
return max_length
# Trace through the example
trace_algorithm("xyzzy")
Processing string: xyzzy Step | Char | Window | Distinct | Max Length --------------------------------------------- 1 | x | x | 1 | 1 2 | y | xy | 2 | 2 3 | z | xyz | 3 | 2 4 | z | yz | 2 | 2 5 | y | yzzy | 2 | 4
Alternative Approach Using Dictionary
We can also solve this using a regular dictionary instead of Counter ?
def longest_substring_dict(s):
if len(s) < 2:
return len(s)
start = 0
char_count = {}
max_length = 0
for end in range(len(s)):
# Add current character
char_count[s[end]] = char_count.get(s[end], 0) + 1
# Shrink window if more than 2 distinct characters
while len(char_count) > 2:
char_count[s[start]] -= 1
if char_count[s[start]] == 0:
del char_count[s[start]]
start += 1
max_length = max(max_length, end - start + 1)
return max_length
# Test with multiple examples
test_cases = ["xyzzy", "abcabcbb", "bbbbb", "pwwkew", ""]
for test in test_cases:
result = longest_substring_dict(test)
print(f"'{test}' ? {result}")
'xyzzy' ? 4 'abcabcbb' ? 2 'bbbbb' ? 5 'pwwkew' ? 3 '' ? 0
Time and Space Complexity
| Complexity | Value | Explanation |
|---|---|---|
| Time | O(n) | Each character visited at most twice |
| Space | O(1) | Dictionary stores at most 3 characters |
Conclusion
The sliding window technique efficiently finds the longest substring with at most 2 distinct characters in O(n) time. The key insight is maintaining a window that shrinks when constraints are violated, ensuring optimal performance.
