Shortest subarray to be removed to make all Array elements unique
Given an array arr[] containing N elements, the task is to remove a subarray of minimum possible length from the given array such that all remaining elements are distinct. Print the minimum possible length of the subarray.
Examples:
Input: N = 5, arr[] = {1, 2, 1, 2, 3}
Output: 2
Explanation:
Remove the sub array {2, 1} to make the elements distinct.
Input: N = 5, arr[] = {1, 2, 3, 4, 5}
Output: 0
Explanation:
Elements are already distinct.
Naive Approach: The naive approach for this problem is to simply check for all the possible subarrays and find the length of the smallest subarray after removal of which all the elements in the array become distinct.
Time complexity: O(N3)
Efficient Approach:
- Let ans be the length of the minimum subarray that on removing from the given array, makes the elements of the array unique.
- We can easily observe that if all array elements become distinct after removing a subarray of length ans, then this condition is also true for all values greater than ans.
- This means that the solution for this problem is a monotonically increasing function and we can apply binary search on the answer.
- Now, for a particular length K of subarray, we can check if elements of prefix and suffix of all sub arrays of length K are distinct or not.
- We can do this by using a sliding window technique.
- Use a hash map to store the frequencies of elements in prefix and suffix, on moving the window forward, increment frequency of the last element of prefix and decrement frequency of the first element of suffix.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
bool check( int a[], int n, int k)
{
map< int , int > m;
int extra = 0;
for ( int i = k; i < n; i++)
m[a[i]]++;
for ( auto x : m)
extra += x.second - 1;
if (extra == 0)
return true ;
for ( int i = 1; i + k - 1 < n; i++) {
if (m[a[i + k - 1]] > 1)
extra--;
m[a[i + k - 1]]--;
m[a[i - 1]]++;
if (m[a[i - 1]] > 1)
extra++;
if (extra == 0)
return true ;
}
return false ;
}
int minlength( int a[], int n)
{
int lo = 0, hi = n + 1;
int ans = 0;
while (lo < hi) {
int mid = (lo + hi) / 2;
if (check(a, n, mid)) {
ans = mid;
hi = mid;
}
else
lo = mid + 1;
}
return ans;
}
int main()
{
int a[5] = { 1, 2, 1, 2, 3 };
int n = sizeof (a) / sizeof ( int );
cout << minlength(a, n);
}
|
Java
import java.util.*;
import java.lang.*;
class GFG{
static boolean check( int a[], int n, int k)
{
Map<Integer, Integer> m = new HashMap<>();
int extra = 0 ;
for ( int i = k; i < n; i++)
m.put(a[i], m.getOrDefault(a[i], 0 ) + 1 );
for (Integer x : m.values())
extra += x - 1 ;
if (extra == 0 )
return true ;
for ( int i = 1 ; i + k - 1 < n; i++)
{
if (m.get(a[i + k - 1 ]) > 1 )
extra--;
m.put(a[i + k - 1 ],
m.get(a[i + k - 1 ]) - 1 );
m.put(a[i - 1 ], m.get(a[i - 1 ]) + 1 );
if (m.get(a[i - 1 ]) > 1 )
extra++;
if (extra == 0 )
return true ;
}
return false ;
}
static int minlength( int a[], int n)
{
int lo = 0 , hi = n + 1 ;
int ans = 0 ;
while (lo < hi)
{
int mid = (lo + hi) / 2 ;
if (check(a, n, mid))
{
ans = mid;
hi = mid;
}
else
lo = mid + 1 ;
}
return ans;
}
public static void main (String[] args)
{
int a[] = { 1 , 2 , 1 , 2 , 3 };
int n = a.length;
System.out.println(minlength(a, n));
}
}
|
Python3
from collections import defaultdict
def check(a, n, k):
m = defaultdict( int )
extra = 0
for i in range (k, n):
m[a[i]] + = 1
for x in m:
extra + = m[x] - 1
if (extra = = 0 ):
return True
for i in range ( 1 , i + k - 1 < n):
if (m[a[i + k - 1 ]] > 1 ):
extra - = 1
m[a[i + k - 1 ]] - = 1
m[a[i - 1 ]] + = 1
if (m[a[i - 1 ]] > 1 ):
extra + = 1
if (extra = = 0 ):
return True
return False
def minlength(a, n):
lo = 0
hi = n + 1
ans = 0
while (lo < hi):
mid = (lo + hi) / / 2
if (check(a, n, mid)):
ans = mid
hi = mid
else :
lo = mid + 1
return ans
if __name__ = = "__main__" :
a = [ 1 , 2 , 1 , 2 , 3 ]
n = len (a)
print (minlength(a, n))
|
C#
using System;
using System.Collections.Generic;
class GFG{
static bool check( int []a, int n, int k)
{
Dictionary< int ,
int > m = new Dictionary< int ,
int >();
int extra = 0;
for ( int i = k; i < n; i++)
if (m.ContainsKey(a[i]))
m[a[i]] = m[a[i]] + 1;
else
m.Add(a[i], 1);
foreach ( int x in m.Keys)
extra += m[x] - 1;
if (extra == 0)
return true ;
for ( int i = 1; i + k - 1 < n; i++)
{
if (m[a[i + k - 1]] > 1)
extra--;
m[a[i + k - 1]] = m[a[i + k - 1]] - 1;
m[a[i - 1]] = m[a[i - 1]] + 1;
if (m[a[i - 1]] > 1)
extra++;
if (extra == 0)
return true ;
}
return false ;
}
static int minlength( int []a, int n)
{
int lo = 0, hi = n + 1;
int ans = 0;
while (lo < hi)
{
int mid = (lo + hi) / 2;
if (check(a, n, mid))
{
ans = mid;
hi = mid;
}
else
lo = mid + 1;
}
return ans;
}
public static void Main(String[] args)
{
int []a = { 1, 2, 1, 2, 3 };
int n = a.Length;
Console.WriteLine(minlength(a, n));
}
}
|
Javascript
<script>
function check(a, n, k)
{
let m = new Map();
let extra = 0;
for (let i = k; i < n; i++)
m.set(a[i], m.get(a[i])== null ? 1 :m.get(a[i])+ 1);
for (let x of m.values())
extra += x - 1;
if (extra == 0)
return true ;
for (let i = 1; i + k - 1 < n; i++)
{
if (m.get(a[i + k - 1]) > 1)
extra--;
m.set(a[i + k - 1],
m.get(a[i + k - 1]) - 1);
m.set(a[i - 1], m.get(a[i - 1]) + 1);
if (m.get(a[i - 1]) > 1)
extra++;
if (extra == 0)
return true ;
}
return false ;
}
function minlength(a,n)
{
let lo = 0, hi = n + 1;
let ans = 0;
while (lo < hi)
{
let mid = Math.floor((lo + hi) / 2);
if (check(a, n, mid))
{
ans = mid;
hi = mid;
}
else
lo = mid + 1;
}
return ans;
}
let a = [1, 2, 1, 2, 3 ];
let n = a.length;
document.write(minlength(a, n));
</script>
|
Time Complexity: O(N * log(N)), where N is the size of the array, This is because the function “check” runs in O(n) time, and the function “minlength” performs a binary search on the length of the subarray, which takes O(log n) time.
Auxiliary Space: O(N), as it uses a hash map to store the frequencies of elements in each subarray, which can have up to n elements.
Last Updated :
29 Apr, 2023
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...