Maximum number of Unique integers in Sub-Array of given size

Given an array of N integers and a number M. The task is to find out the maximum number of unique integers among all possible contiguous subarrays of size M.

Examples:

Input : arr[] = {5, 3, 5, 2, 3, 2}, M = 3
Output : 3
Explanation:
In the sample test case, there are 4 subarrays of size 3.
s1 = (5, 3, 5)- Has 2 unique numbers.
s2 = (3, 5, 2)- Has 3 unique numbers.
s3 = (5, 2, 3)- Has 3 unique numbers.
s4 = (2, 3, 2)- Has 2 unique numbers.
In these subarrays, there are 2, 3, 3, 2 unique numbers, respectively.
The maximum amount of unique numbers among all possible contiguous subarrays is 3.

Input : arr[] = {5, 5, 5, 5, 5, 5}, M = 3
Output : 1

Naive Approach:



  1. Generate all subarrays of size M.
  2. Count unique number for each subarray.
    • Check whether it is greater than the previous maximum unique number or not, if yes, replace it with the previous maximum unique number.
  3. Continue until we generate all possible subarrays.

Below is the implementation of the above approach:

C++

// A C++ programme to find maximum distinct elements
// in a subarray of size k
#include<bits/stdc++.h>
using namespace std;
//Function to find maximun unique element in 
//a subarray of size k
int maxUniqueNum(int a[],int N,int M)
{
    int maxUnique=0;
    //search every subarray of size k 
    //and find how many unique element present
    for(int i=0;i<N-M;i++)
    {
        //create an empty set to store the unique elements
        set<int> s;
        for(int j=0;j<M;j++)
        {
            //insert all elements
            //duplicate elements are not stored in set
            s.insert(a[i+j]);
        }
        //update the maxUnique 
        if(s.size()>maxUnique)
        {
            maxUnique=s.size();
        }
    }
    return maxUnique;
}
      
int main()
{
    int arr[] = {5, 3, 5, 2, 3, 2};
    int M=3,N=sizeof(arr)/sizeof(arr[0]);
    cout<<maxUniqueNum(arr,N,M)<<endl;
      
}

Java

// Java Program to find maximum number of
// Unique integers in Sub-Array
// of given size
  
import java.util.*;
class GFG {
  
    // Function to find maximum number of
    // Unique integers in Sub-Array
    // of given size
    public static int maxUniqueNum(int arr[],
                                   int N, int M)
    {
        int maxUnique = 0;
  
        // Generate all subarrays of size M
        for (int i = 0; i < N - M; i++) {
            int currentUnique = 0;
  
            HashMap<Integer, Integer> map = new HashMap<Integer, Integer>();
  
            for (int k = i; k < i + M; k++) {
  
                // if the key is new to the map,
                // push the key in map and increment
                // count for unique number
                if (!map.containsKey(arr[k])) {
                    map.put(arr[i], 1);
                    currentUnique++;
                    continue;
                }
            }
  
            if (currentUnique > maxUnique)
                maxUnique = currentUnique;
        }
  
        return maxUnique;
    }
  
    // Driver Code
    public static void main(String[] args)
    {
        int[] arr = { 5, 3, 5, 2, 3, 2 };
        int N = 6;
  
        int M = 3;
  
        System.out.println(maxUniqueNum(arr, N, M));
    }
}

Output:

3

Time Complexity : O(M * N)
Auxiliary Space : O(M)

Efficient Solution An efficient solution is to use window sliding technique. We maintain a single hash table for storing unique elements of every window.
1) Store counts of first M elements in a hash map.
2) Traverse from (M+1)-th element and for every element, add it to hash map and remove first element of previous window.

Below is the implementation of the above approach:

C++

// An efficient Approach to count distinct elements in
// every window of size k
#include<bits/stdc++.h>
using namespace std;
//Function to find maximum unique element in
//a subarray of size k
int max_U_element(int a[],int N,int M)
{
    //map to store the unique elements and their size
    map<int,int> hash;
    //Number of unique elements in an window
    int dist_count=0;    
    int res=0;   //Maximum unique element in a window
    //store all elements till size k i.e.
    //storing first window
    for(int i=0;i<M;i++)
    {
        //found an unique element
        if(hash.find(a[i])==hash.end())
        {
            hash.insert(make_pair(a[i],1));
            dist_count++;
        }
        //an Duplicate element inserting
        else
        {
            //Update the size of that element
            hash[a[i]]++;
        }
    }
    res=dist_count;
    //Traverse till the end of array
    for(int i=M;i<N;i++)
    {
        //Remove fist element from map
        if(hash[a[i-M]]==1)
        {
            //when element present only one time
            // in window so delete this
            hash.erase(a[i-M]);
            dist_count--;
        }
        else
        {
            //when multiple time element has occurred
            // in window so decrease size by one
            hash[a[i-M]]--;
        }
        //Add new element to map
        //If element is unique to map
        //increment count
        if(hash.find(a[i])==hash.end())
        {
            hash.insert(make_pair(a[i],1));
            dist_count++;
        }
        //Duplicate element found
        //update the size of that element
        else
        {
            hash[a[i]]++;
        }
        //Update the res
        res=max(res,dist_count);
    }
    return res;
}
//Driver code
int main()
{
    int arr[] = {1, 2, 1, 3, 4, 2, 3};
    int M=4,N=sizeof(arr)/sizeof(arr[0]);
    cout<<max_U_element(arr,N,M)<<endl;
  
}

Java

// An efficient Java program to count distinct elements in
// every window of size k
import java.util.HashMap;
  
class maxUniqueNumWindow {
    static int maxUniqueNum(int arr[], int M)
    {
        // Creates an empty hashMap hM
        HashMap<Integer, Integer> hM = new HashMap<Integer, Integer>();
  
        // initialize distinct element count for
        // current window
        int dist_count = 0;
  
        // Traverse the first window and store count
        // of every element in hash map
        for (int i = 0; i < M; i++) {
            if (hM.get(arr[i]) == null) {
                hM.put(arr[i], 1);
                dist_count++;
            }
            else {
                int count = hM.get(arr[i]);
                hM.put(arr[i], count + 1);
            }
        }
   
        int res = dist_count;
  
        // Traverse through the remaining array
        for (int i = M; i < arr.length; i++) {
  
            // Remove first element of previous window
            // If there was only one occurrence, then
            // reduce distinct count.
            if (hM.get(arr[i - M]) == 1) {
                hM.remove(arr[i - M]);
                dist_count--;
            }
  
            else // reduce count of the removed element
            {
                int count = hM.get(arr[i - M]);
                hM.put(arr[i - M], count - 1);
            }
  
            // Add new element of current window
            // If this element appears first time,
            // increment distinct element count
            if (hM.get(arr[i]) == null) {
                hM.put(arr[i], 1);
                dist_count++;
            }
            else // Increment distinct element count
            {
                int count = hM.get(arr[i]);
                hM.put(arr[i], count + 1);
            }
  
            res = Math.max(res, dist_count);
        }
  
        return res;
    }
  
    // Driver method
    public static void main(String arg[])
    {
        int arr[] = { 1, 2, 1, 3, 4, 2, 3 };
        int M = 4;
        System.out.println(maxUniqueNum(arr, M));
    }
}

Output:

4

Time Complexity : O(N)
Auxiliary Space : O(M)



My Personal Notes arrow_drop_up


If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.



Improved By : Milan1999