02. Longest Subarray with At Most Two Distinct Integers
โ GFG solution to the Longest Subarray with At Most Two Distinct Integers problem: find maximum length subarray containing at most 2 distinct elements using sliding window technique. ๐
The problem can be found at the following link: ๐ Question Link
๐งฉ Problem Description
You are given an array arr[] consisting of positive integers. Your task is to find the length of the longest subarray that contains at most two distinct integers.
A subarray is a contiguous sequence of elements within an array. The goal is to find the maximum possible length of such a subarray where the number of unique elements does not exceed 2.
๐ Examples
Example 1
Input: arr[] = [2, 1, 2]
Output: 3
Explanation: The entire array [2, 1, 2] contains at most two distinct integers (2 and 1).
Hence, the length of the longest subarray is 3.Example 2
Input: arr[] = [3, 1, 2, 2, 2, 2]
Output: 5
Explanation: The longest subarray containing at most two distinct integers is [1, 2, 2, 2, 2],
which has a length of 5.Example 3
๐ Constraints
$1 \le \text{arr.size()} \le 10^5$
$1 \le \text{arr}[i] \le 10^5$
โ
My Approach
The optimal approach uses the Sliding Window technique with a Hash Map to efficiently track distinct elements and their frequencies:
Sliding Window + Hash Map
Initialize Variables:
Use two pointers:
left(start of window) andright(end of window).Maintain a hash map to store frequency of elements in current window.
Track
maxLengthto store the result.
Expand Window:
Move
rightpointer and addarr[right]to the hash map.Increment its frequency.
Contract Window:
If hash map size exceeds 2 (more than 2 distinct elements), shrink window from left.
Decrement frequency of
arr[left]and remove it if frequency becomes 0.Move
leftpointer forward.
Update Result:
After each valid window, update
maxLengthwith current window size.
Continue Until End:
Repeat until
rightpointer reaches the end of array.
๐ Time and Auxiliary Space Complexity
Expected Time Complexity: O(n), where n is the size of the array. Each element is visited at most twice (once by right pointer and once by left pointer).
Expected Auxiliary Space Complexity: O(k), where k is the number of distinct elements in the current window. In the worst case, k โค 2, so effectively O(1) additional space.
๐งโ๐ป Code (C++)
โก View Alternative Approaches with Code and Analysis
๐ 2๏ธโฃ Two Variable Tracking Approach
๐ก Algorithm Steps:
Initialize two variables
firstandsecondto represent the two distinct numbers allowed in the window, andfirstIdx,secondIdxto store their most recent positions.Traverse the array with a right pointer:
If the current element equals
firstorsecond, update the corresponding index.If a third new element appears:
Determine which of the two existing numbers appeared earlier (minimum of
firstIdxandsecondIdx).Move the left pointer just past that index to ensure only two distinct elements remain.
Replace the older number (
firstorsecond) with the new element and update its index.
Update the maximum length after each iteration.
๐ Complexity Analysis:
Time: โฑ๏ธ O(n)
Auxiliary Space: ๐พ O(1) - Constant space
โ
Why This Approach?
Optimal space complexity with O(1) memory usage.
No hash map overhead, direct variable tracking.
Efficient for small distinct element tracking.
๐ 3๏ธโฃ Frequency Array Optimization
๐ก Algorithm Steps:
Use a frequency array (e.g.,
freq[100001]) assuming all elements fall within a known small integer range.Initialize variables:
left = 0,distinctCount = 0,maxLen = 0.Traverse using a right pointer:
If
arr[right]is added to the window for the first time (freq[arr[right]] == 0), incrementdistinctCount.Increase the count for
arr[right].
If
distinctCount > 2, shrink the window:Decrease the count of
arr[left].If its count becomes 0, decrement
distinctCount.Move
leftforward.
At each iteration, update
maxLenas the maximum valid window size.
๐ Complexity Analysis:
Time: โฑ๏ธ O(n)
Auxiliary Space: ๐พ O(k) where k = range of elements
โ
Why This Approach?
Faster than hash map for known small ranges.
Cache-friendly array access pattern.
No need for key-value mappingโconstant-time operations.
๐ 4๏ธโฃ STL Set-Based Tracking
๐ก Algorithm Steps:
Use an
unordered_map<int, int>to store frequency of elements and aunordered_set<int>to track the number of unique elements in the current window.Initialize
left = 0,maxLen = 0.Traverse using a right pointer:
Add
arr[right]to the map and insert into the set.
If the set size exceeds 2 (more than 2 distinct elements), shrink the window:
Decrease count of
arr[left].If the count becomes 0, remove it from the set.
Move the
leftpointer forward.
At each step, update
maxLenwith the current valid window size.
๐ Complexity Analysis:
Time: โฑ๏ธ O(n)
Auxiliary Space: ๐พ O(n)
โ
Why This Approach?
Clear separation of concerns with set and map.
Easy to trace which elements are currently active.
Good for debugging and understanding logic flow.
5๏ธโฃ ๐ Ordered Map Sliding Window
๐ก Algorithm Steps:
Use a
std::map<int, int>(ordered map) to count the elements within the sliding window.Expand the window to the right by moving pointer
j; increase the count fora[j].If the map contains more than 2 distinct elements, shrink the window from the left:
Decrement the count for
a[i].If the count becomes 0, erase the element from the map.
Track the maximum window size during each iteration.
๐ Complexity Analysis:
Time: โฑ๏ธ O(n log k), where k โค 2 here
Auxiliary Space: ๐พ O(k)
โ
Why This Approach?
Maintains ordering automatically with
std::map.Shrinks window cleanly using count + erase.
Good readability and debugging via sorted structure.
๐ ๐ Comparison of Approaches
๐ Approach
โฑ๏ธ Time Complexity
๐พ Space Complexity
โ Pros
โ ๏ธ Cons
๐ Hash Map Sliding Window
๐ข O(n)
๐ก O(k)
โก Clean code, general solution
๐พ Hash map overhead
๐ Two Variable Tracking
๐ข O(n)
๐ข O(1)
๐ Optimal space, fastest runtime
๐งฎ Complex logic, harder to debug
๐บ Frequency Array
๐ข O(n)
๐ก O(range)
โก Cache-friendly, fast access
๐พ Limited to known small ranges
๐ STL Set-Based
๐ข O(n)
๐ก O(n)
๐ง Clear logic, STL optimized
๐พ Extra space for set structure
โฐ Ordered Map Sliding Window
๐ก O(n log k)
๐ข O(1)
๐ Predictable, no hash collisions
๐พ Slightly slower per op
๐ Best Choice Recommendation
๐ฏ Scenario
๐๏ธ Recommended Approach
๐ฅ Performance Rating
โก Maximum performance, competitive programming
๐ฅ Two Variable Tracking
โ โ โ โ โ
๐ง Production code, readability important
๐ฅ Hash Map Sliding Window
โ โ โ โ โ
๐ Known small element range
๐ฅ Frequency Array
โ โ โ โ โ
๐ฏ Educational purposes, clear logic
๐๏ธ STL Set-Based
โ โ โ โโ
๐ Readability / simplicity
๐ Ordered Map Sliding Window
โ โ โ โ โ
๐งโ๐ป Code (Java)
๐ Code (Python)
๐ง Contribution and Support
For discussions, questions, or doubts related to this solution, feel free to connect on LinkedIn: ๐ฌ Any Questions?. Let's make this learning journey more collaborative!
โญ If you find this helpful, please give this repository a star! โญ
๐Visitor Count
Last updated