s, return the maximum length of a substring such that it contains at most two occurrences of each character.
Example 1:
Input: s = "bcbbbcba"
Output: 4
Explanation:
The following substring has a length of 4 and contains at most two occurrences of each character:"bcbbbcba".Example 2:
Input: s = "aaaa"
Output: 2
Explanation:
The following substring has a length of 2 and contains at most two occurrences of each character:"aaaa".
Constraints:
2 <= s.length <= 100s consists only of lowercase English letters.Problem Overview: Given a string s, find the maximum length of a substring where every character appears at most two times. The substring must remain contiguous, so the challenge is maintaining character counts while expanding or shrinking the window efficiently.
Approach 1: Sorting and Two-Pointers (O(n log n) time, O(n) space)
This approach conceptually groups characters and uses a two-pointer style scan to maintain a valid segment where no character frequency exceeds two. After sorting auxiliary structures that track characters and indices, you move two pointers to maintain the longest valid span. When a character appears more than twice, shift the left pointer forward until the constraint is restored.
The core idea is similar to classic two pointers problems: expand the right pointer to include new characters and shrink the left pointer when constraints break. Sorting helps organize character occurrences but adds extra overhead. Time complexity is O(n log n) due to sorting, and space complexity is O(n) for auxiliary storage.
This method demonstrates the constraint-handling logic clearly but is rarely the optimal implementation because the substring is already sequential in the original string.
Approach 2: HashMap Sliding Window (O(n) time, O(1) space)
The optimal solution uses a sliding window combined with a frequency map. Maintain two pointers left and right that define the current substring. As you expand right, increment the count of s[right] in a hash table. If any character count exceeds two, move left forward while decrementing frequencies until the substring becomes valid again.
At every step, compute the window size right - left + 1 and update the maximum length. Each character enters and leaves the window at most once, which guarantees linear time. Because the alphabet size is bounded (typically lowercase English letters), the space complexity is effectively O(1).
This pattern appears frequently in substring problems where you enforce limits on character frequency. The sliding window ensures you never reprocess characters unnecessarily, making it both efficient and easy to implement.
Recommended for interviews: The sliding window with a hash map is the expected solution. Interviewers want to see that you recognize substring constraint problems and immediately apply the sliding window pattern. Explaining a brute-force idea or a less optimal pointer approach shows understanding, but implementing the O(n) window solution demonstrates strong problem-solving instincts.
This approach leverages sorting and the two-pointer technique to solve the problem efficiently. By sorting the input initially, we can use two pointers to find the desired target without checking all possible pairs, which makes the solution more optimized compared to a brute force approach.
The C solution uses qsort to sort the array. Then, it applies the two-pointer strategy, moving indices towards the center depending on the sum of elements at current pointers being smaller or larger than the target.
Time Complexity: O(n log n) due to sorting, and O(n) for the two-pointer search, resulting in O(n log n) total.
Space Complexity: O(1) as no additional space proportional to input size is used.
This approach utilizes a hashmap to map from element to its index for efficient look-ups of complement values required to reach the target. The idea is to iterate through the array and check if the complement (target - current element) exists in the map, which can be achieved in constant time.
In this C solution, a static hash array is used to remember if a specific number has been encountered, allowing efficient O(1) checks for complements.
Time Complexity: O(n) because each number and its complement are processed in constant time.
Space Complexity: O(n) due to the storage in the hash map.
We use two pointers i and j to maintain a sliding window, and an array cnt to record the occurrence times of each character in the window.
In each iteration, we add the character c at the pointer j into the window, then check if cnt[c] is greater than 2. If it is, we move the pointer i to the right until cnt[c] is less than or equal to 2. At this point, we update the answer ans = max(ans, j - i + 1).
Finally, we return the answer ans.
The time complexity is O(n), where n is the length of the string s. The space complexity is O(|\Sigma|), where \Sigma is the character set, and in this problem, \Sigma = 26.
Python
Java
C++
Go
TypeScript
| Approach | Complexity |
|---|---|
| Approach 1: Sorting and Two-Pointers | Time Complexity: O(n log n) due to sorting, and O(n) for the two-pointer search, resulting in O(n log n) total. |
| Approach 2: HashMap (or HashSet for Some Languages) | Time Complexity: O(n) because each number and its complement are processed in constant time. |
| Two Pointers | — |
| Approach | Time | Space | When to Use |
|---|---|---|---|
| Sorting and Two-Pointers | O(n log n) | O(n) | Useful for understanding constraint handling with pointer expansion and contraction, though not optimal for substring problems. |
| HashMap Sliding Window | O(n) | O(1) | Best choice for contiguous substring problems with frequency limits. Preferred in interviews and production code. |
3090 Maximum Length Substring With Two Occurrences || Brute Force to Optimal ✅ || Sliding Window • Ayush Rao • 2,094 views views
Watch 9 more video solutions →Practice Maximum Length Substring With Two Occurrences with our built-in code editor and test cases.
Practice on FleetCode