Find length of the longest subarray containing atmost two distinct integers
Last Updated :
17 May, 2023
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:
- Initialize a variable “size” to 0 to store the size of the largest subarray with at most two distinct elements.
- Generate all subarrays of the input array using two nested loops.
- For each subarray, create a set to store distinct elements and check if the subarray has at most two distinct elements by iterating over the elements of the subarray and adding them to the set. If the size of the set exceeds 2, break out of the loop.
- If the subarray has at most two distinct elements, update the “size” variable with the length of the subarray if it is greater than the current value of “size”.
- Return the “size” variable as the output.
Here is the implementation of above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int totalElements( int N, vector< int > arr) {
int size = 0;
for ( int i = 0; i < N; i++) {
for ( int j = i; j < N; j++) {
unordered_set< int > distinct;
for ( int k = i; k <= j; k++) {
distinct.insert(arr[k]);
if (distinct.size() > 2) {
break ;
}
}
if (distinct.size() <= 2) {
size = max(size, j-i+1);
}
}
}
return size;
}
int main() {
int N = 6;
vector< int > arr = {0, 1, 2, 2, 2, 2};
int ans = totalElements(N, arr);
cout << ans << endl;
return 0;
}
|
Java
import java.util.*;
public class Main {
public static int totalElements( int N, int [] arr) {
int size = 0 ;
for ( int i = 0 ; i < N; i++) {
for ( int j = i; j < N; j++) {
Set<Integer> distinct = new HashSet<>();
for ( int k = i; k <= j; k++) {
distinct.add(arr[k]);
if (distinct.size() > 2 ) {
break ;
}
}
if (distinct.size() <= 2 ) {
size = Math.max(size, j-i+ 1 );
}
}
}
return size;
}
public static void main(String[] args) {
int N = 6 ;
int [] arr = { 0 , 1 , 2 , 2 , 2 , 2 };
int ans = totalElements(N, arr);
System.out.println(ans);
}
}
|
Python3
def totalElements(N, arr):
size = 0
for i in range (N):
for j in range (i, N):
distinct = set ()
for k in range (i, j + 1 ):
distinct.add(arr[k])
if len (distinct) > 2 :
break
if len (distinct) < = 2 :
size = max (size, j - i + 1 )
return size
if __name__ = = "__main__" :
N = 6
arr = [ 0 , 1 , 2 , 2 , 2 , 2 ]
ans = totalElements(N, arr)
print (ans)
|
C#
using System;
using System.Collections.Generic;
public class Program
{
public static int TotalElements( int N, int [] arr)
{
int size = 0;
for ( int i = 0; i < N; i++)
{
for ( int j = i; j < N; j++)
{
HashSet< int > distinct = new HashSet< int >();
for ( int k = i; k <= j; k++)
{
distinct.Add(arr[k]);
if (distinct.Count > 2)
{
break ;
}
}
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};
int ans = TotalElements(N, arr);
Console.WriteLine(ans);
}
}
|
Javascript
function totalElements(N, arr) {
let size = 0;
for (let i = 0; i < N; i++) {
for (let j = i; j < N; j++) {
const distinct = new Set();
for (let k = i; k <= j; k++) {
distinct.add(arr[k]);
if (distinct.size > 2) {
break ;
}
}
if (distinct.size <= 2) {
size = Math.max(size, j-i+1);
}
}
}
return size;
}
const N = 6;
const arr = [0, 1, 2, 2, 2, 2];
const ans = totalElements(N, arr);
console.log(ans);
|
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:
- Create an empty map<int, int> mp to store the frequency of each element.
- Initialize i = 0, j = 0, and n=arr.size().
- Initialize size = 0 to store the maximum length of the subarray.
- While j is less than n:
- Increment the frequency of the current element(arr[j]) in the map mp.
- While the size of the map mp is greater than 2,
- Decrement the frequency of the element at position i (arr[i]) in the map mp.
- If the frequency of the element at position i in the map mp becomes 0, remove it from the map.
- Increment i.
- Update the maximum length of the subarray by taking the maximum of the current size and (j – i + 1).
- Increment j.
- Return the size.
Below is the implementation for the above approach:
C++
#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;
}
int main()
{
int N = 6;
vector< int > arr = { 0, 1, 2, 2, 2, 2 };
int ans = totalElements(N, arr);
cout << ans;
return 0;
}
|
Java
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 ));
int ans = totalElements(N, arr);
System.out.println(ans);
}
}
|
Python3
import sys
from collections import defaultdict
def totalElements(N, arr):
mp = defaultdict( int )
i = 0
j = 0
n = len (arr)
size = 0
while j < n:
mp[arr[j]] + = 1
while len (mp) > 2 :
mp[arr[i]] - = 1
if mp[arr[i]] = = 0 :
del mp[arr[i]]
i + = 1
size = max (size, j - i + 1 )
j + = 1
return size
if __name__ = = "__main__" :
N = 6
arr = [ 0 , 1 , 2 , 2 , 2 , 2 ]
ans = totalElements(N, arr)
print (ans)
|
C#
using System;
using System.Collections.Generic;
class GFG
{
static int TotalElements( int N, List< int > arr)
{
Dictionary< int , int > mp
= new Dictionary< int , int >();
int i = 0, j = 0, n = arr.Count;
int size = 0;
while (j < n) {
if (mp.ContainsKey(arr[j])) {
mp[arr[j]]++;
}
else {
mp.Add(arr[j], 1);
}
while (mp.Count > 2) {
mp[arr[i]]--;
if (mp[arr[i]] == 0) {
mp.Remove(arr[i]);
}
i++;
}
size = Math.Max(size, j - i + 1);
j++;
}
return size;
}
static void Main( string [] args) {
int N = 6;
List< int > arr = new List< int >{ 0, 1, 2, 2, 2, 2 };
int ans = TotalElements(N, arr);
Console.WriteLine(ans);
}
}
|
Javascript
function totalElements(N, arr) {
const mp = new Map();
let i = 0, j = 0, n = arr.length;
let size = 0;
while (j < n) {
if (mp.has(arr[j])) {
mp.set(arr[j], mp.get(arr[j]) + 1);
}
else {
mp.set(arr[j], 1);
}
while (mp.size > 2) {
mp.set(arr[i], mp.get(arr[i]) - 1);
if (mp.get(arr[i]) === 0) {
mp. delete (arr[i]);
}
i++;
}
size = Math.max(size, j - i + 1);
j++;
}
return size;
}
const N = 6;
const arr = [0, 1, 2, 2, 2, 2];
const ans = totalElements(N, arr);
console.log(ans);
|
Time complexity: O(N)
Auxiliary Space: O(1)
Share your thoughts in the comments
Please Login to comment...