Open In App

Find length of the longest subarray containing atmost two distinct integers

Given an array arr[] containing N elements, the task is to find the length of the longest subarray of an input array containing at most two distinct integers.

Examples:



Input: N = 3, arr[ ] = { 2, 1, 2 }
Output: 3
Explanation: We can pick from all three elements.

Input: N = 6, arr[ ] = { 0, 1, 2, 2, 2, 2 }
Output: 5
Explanation: It’s optimal to pick elements(0-indexed) [1, 2, 3, 4, 5].



Approach: Brute-Force approach

The steps for the approach are:

Here is the implementation of above approach:




#include <bits/stdc++.h>
using namespace std;
 
int totalElements(int N, vector<int> arr) {
    int size = 0; // Size of the largest subarray with at most two distinct elements
     
    // Generate all subarrays
    for (int i = 0; i < N; i++) {
        for (int j = i; j < N; j++) {
            // Create a set to store distinct elements
            unordered_set<int> distinct;
             
            // Check if the subarray has at most two distinct elements
            for (int k = i; k <= j; k++) {
                distinct.insert(arr[k]);
                if (distinct.size() > 2) {
                    break;
                }
            }
             
            // Update the size of the largest subarray
            if (distinct.size() <= 2) {
                size = max(size, j-i+1);
            }
        }
    }
     
    return size;
}
 
// Driver code
int main() {
    int N = 6;
    vector<int> arr = {0, 1, 2, 2, 2, 2};
     
    // Function call
    int ans = totalElements(N, arr);
    cout << ans << endl;
     
    return 0;
}




import java.util.*;
 
public class Main {
    public static int totalElements(int N, int[] arr) {
        int size = 0; // Size of the largest subarray with at most two distinct elements
         
        // Generate all subarrays
        for (int i = 0; i < N; i++) {
            for (int j = i; j < N; j++) {
                // Create a set to store distinct elements
                Set<Integer> distinct = new HashSet<>();
                 
                // Check if the subarray has at most two distinct elements
                for (int k = i; k <= j; k++) {
                    distinct.add(arr[k]);
                    if (distinct.size() > 2) {
                        break;
                    }
                }
                 
                // Update the size of the largest subarray
                if (distinct.size() <= 2) {
                    size = Math.max(size, j-i+1);
                }
            }
        }
         
        return size;
    }
     
    // Driver code
    public static void main(String[] args) {
        int N = 6;
        int[] arr = {0, 1, 2, 2, 2, 2};
         
        // Function call
        int ans = totalElements(N, arr);
        System.out.println(ans);
    }
}




def totalElements(N, arr):
    size = 0 # Size of the largest subarray with at most two distinct elements
     
    # Generate all subarrays
    for i in range(N):
        for j in range(i, N):
            # Create a set to store distinct elements
            distinct = set()
             
            # Check if the subarray has at most two distinct elements
            for k in range(i, j+1):
                distinct.add(arr[k])
                if len(distinct) > 2:
                    break
             
            # Update the size of the largest subarray
            if len(distinct) <= 2:
                size = max(size, j-i+1)
     
    return size
 
 
# Driver code
if __name__ == "__main__":
    N = 6
    arr = [0, 1, 2, 2, 2, 2]
     
    # Function call
    ans = totalElements(N, arr)
    print(ans)




using System;
using System.Collections.Generic;
 
public class Program
{
    public static int TotalElements(int N, int[] arr)
    {
        int size = 0; // Size of the largest subarray with at most two distinct elements
 
        // Generate all subarrays
        for (int i = 0; i < N; i++)
        {
            for (int j = i; j < N; j++)
            {
                // Create a set to store distinct elements
                HashSet<int> distinct = new HashSet<int>();
 
                // Check if the subarray has at most two distinct elements
                for (int k = i; k <= j; k++)
                {
                    distinct.Add(arr[k]);
                    if (distinct.Count > 2)
                    {
                        break;
                    }
                }
 
                // Update the size of the largest subarray
                if (distinct.Count <= 2)
                {
                    size = Math.Max(size, j - i + 1);
                }
            }
        }
 
        return size;
    }
 
    public static void Main()
    {
        int N = 6;
        int[] arr = new int[] {0, 1, 2, 2, 2, 2};
 
        // Function call
        int ans = TotalElements(N, arr);
        Console.WriteLine(ans);
    }
}




function totalElements(N, arr) {
    let size = 0; // Size of the largest subarray with at most two distinct elements
     
    // Generate all subarrays
    for (let i = 0; i < N; i++) {
        for (let j = i; j < N; j++) {
            // Create a set to store distinct elements
            const distinct = new Set();
             
            // Check if the subarray has at most two distinct elements
            for (let k = i; k <= j; k++) {
                distinct.add(arr[k]);
                if (distinct.size > 2) {
                    break;
                }
            }
             
            // Update the size of the largest subarray
            if (distinct.size <= 2) {
                size = Math.max(size, j-i+1);
            }
        }
    }
     
    return size;
}
 
const N = 6;
const arr = [0, 1, 2, 2, 2, 2];
 
// Function call
const ans = totalElements(N, arr);
console.log(ans);

Output
5

The time complexity of this approach is O(N^3) because there are O(N^2) subarrays and each subarray takes O(N) time to check. 

The space complexity is O(1) because we are not using any extra space apart from a few variables to store the results.

Optimal Approach: To solve the problem follow the below idea:

The idea is to use the sliding window approach and use the map to store the contiguous frequency of the elements.

Follow the steps to solve the problem:

Below is the implementation for the above approach:




// C++ code for the above approach:
#include <bits/stdc++.h>
using namespace std;
 
int totalElements(int N, vector<int>& arr)
{
 
    map<int, int> mp;
 
    int i = 0, j = 0, n = arr.size();
 
    int size = 0;
 
    while (j < n) {
 
        mp[arr[j]]++;
 
        while (mp.size() > 2) {
 
            mp[arr[i]]--;
 
            if (mp[arr[i]] == 0) {
 
                mp.erase(arr[i]);
            }
 
            i++;
        }
 
        size = max(size, j - i + 1);
 
        j++;
    }
 
    return size;
}
 
// Drivers code
int main()
{
    int N = 6;
    vector<int> arr = { 0, 1, 2, 2, 2, 2 };
 
    // Function Call
    int ans = totalElements(N, arr);
    cout << ans;
    return 0;
}




import java.util.*;
 
public class Main {
    public static int totalElements(int N, ArrayList<Integer> arr) {
        Map<Integer, Integer> mp = new HashMap<>();
 
        int i = 0, j = 0, n = arr.size();
 
        int size = 0;
 
        while (j < n) {
            int current = arr.get(j);
            mp.put(current, mp.getOrDefault(current, 0) + 1);
 
            while (mp.size() > 2) {
                int left = arr.get(i);
                mp.put(left, mp.get(left) - 1);
 
                if (mp.get(left) == 0) {
                    mp.remove(left);
                }
 
                i++;
            }
 
            size = Math.max(size, j - i + 1);
 
            j++;
        }
 
        return size;
    }
 
    public static void main(String[] args) {
        int N = 6;
        ArrayList<Integer> arr = new ArrayList<>(Arrays.asList(0, 1, 2, 2, 2, 2));
 
        // Function Call
        int ans = totalElements(N, arr);
        System.out.println(ans);
    }
}




import sys
from collections import defaultdict
 
def totalElements(N, arr):
    # Create a dictionary to store frequency of elements
    mp = defaultdict(int)
 
    i = 0  # Left pointer
    j = 0  # Right pointer
    n = len(arr)  # Length of the input array
 
    size = 0  # Size of the largest subarray with at most two distinct elements
 
    while j < n:
        # Update frequency of current element in the dictionary
        mp[arr[j]] += 1
 
        while len(mp) > 2:
            # Decrement frequency of leftmost element in the dictionary
            mp[arr[i]] -= 1
 
            # If frequency becomes zero, remove it from the dictionary
            if mp[arr[i]] == 0:
                del mp[arr[i]]
 
            i += 1  # Move left pointer to the right
 
        # Update the size of the largest subarray
        size = max(size, j - i + 1)
 
        j += 1  # Move right pointer to the right
 
    return size
 
 
# Driver code
if __name__ == "__main__":
    N = 6
    arr = [0, 1, 2, 2, 2, 2]
 
    # Function call
    ans = totalElements(N, arr)
    print(ans)




// C# code for the approach
 
using System;
using System.Collections.Generic;
 
class GFG
{
 
  // Defining the TotalElements function that returns an
  // integer value.
  static int TotalElements(int N, List<int> arr)
  {
 
    // Initializing a dictionary to keep track of the
    // elements and their frequency.
    Dictionary<int, int> mp
      = new Dictionary<int, int>();
 
    // Initializing variables i and j to 0 and n
    // respectively, where n is the length of the given
    // array.
    int i = 0, j = 0, n = arr.Count;
 
    // Initializing the size variable to 0.
    int size = 0;
 
    // Running a while loop until j is less than n.
    while (j < n) {
      // Checking if the dictionary already contains
      // the element at index j.
      if (mp.ContainsKey(arr[j])) {
        // If it does, increment the value of the
        // key (frequency).
        mp[arr[j]]++;
      }
      else {
        // If it doesn't, add the element to the
        // dictionary with frequency 1.
        mp.Add(arr[j], 1);
      }
 
      // Running a while loop until the size of the
      // dictionary becomes greater than 2.
      while (mp.Count > 2) {
        // Decrementing the frequency of the element
        // at index i.
        mp[arr[i]]--;
 
        // Removing the element from the dictionary
        // if its frequency becomes 0.
        if (mp[arr[i]] == 0) {
          mp.Remove(arr[i]);
        }
 
        // Incrementing i.
        i++;
      }
 
      // Calculating the maximum size of the subarray
      // containing at most 2 distinct elements.
      size = Math.Max(size, j - i + 1);
 
      // Incrementing j.
      j++;
    }
 
    // Returning the size of the subarray containing at
    // most 2 distinct elements.
    return size;
  }
 
  // Driver's code
  static void Main(string[] args)     {
    // Initializing the value of N.
    int N = 6;
 
    // Initializing the values of the elements in the
    // array.
    List<int> arr = new List<int>{ 0, 1, 2, 2, 2, 2 };
 
    // Function call
    int ans = TotalElements(N, arr);
 
    Console.WriteLine(ans);
  }
}




// JavaScript code for the approach
 
function totalElements(N, arr) {
 
// Initializing a Map to keep track of the elements and their frequency
const mp = new Map();
 
// Initializing variables i and j to 0 and n
// respectively, where n is the length of the given
// array.
let i = 0, j = 0, n = arr.length;
 
// Initializing the size variable to 0.
let size = 0;
 
// Running a while loop until j is less than n.
while (j < n) {
// Checking if the Map already contains
// the element at index j.
if (mp.has(arr[j])) {
// If it does, increment the value of the
// key (frequency).
mp.set(arr[j], mp.get(arr[j]) + 1);
}
else {
// If it doesn't, add the element to the
// Map with frequency 1.
mp.set(arr[j], 1);
}
// Running a while loop until the size of the
// Map becomes greater than 2.
while (mp.size > 2) {
  // Decrementing the frequency of the element
  // at index i.
  mp.set(arr[i], mp.get(arr[i]) - 1);
 
  // Removing the element from the Map
  // if its frequency becomes 0.
  if (mp.get(arr[i]) === 0) {
    mp.delete(arr[i]);
  }
 
  // Incrementing i.
  i++;
}
 
// Calculating the maximum size of the subarray
// containing at most 2 distinct elements.
size = Math.max(size, j - i + 1);
 
// Incrementing j.
j++;
}
 
// Returning the size of the subarray containing at
// most 2 distinct elements.
return size;
}
 
// Driver's code
const N = 6;
 
// Initializing the values of the elements in the
// array.
const arr = [0, 1, 2, 2, 2, 2];
 
// Function call
const ans = totalElements(N, arr);
 
console.log(ans);

Output
5

Time complexity: O(N)
Auxiliary Space: O(1)


Article Tags :