Open In App

Minimum removals required to make frequency of each array element equal to its value

Given an array arr[] of size N, the task is to find the minimum count of array elements required to be removed such that frequency of each array element is equal to its value

Examples:



Input: arr[] = { 2, 4, 1, 4, 2 } 
Output:
Explanation: 
Removing arr[1] from the array modifies arr[] to { 2, 1, 4, 2 } 
Removing arr[2] from the array modifies arr[] to { 2, 1, 2 } 
Distinct elements in the array are: { 1, 2 } with frequencies 1 and 2 respectively. 
Therefore, the required output is 2.

Input: arr[] = { 2, 7, 1, 8, 2, 8, 1, 8 } 
Output: 5



Approach: The problem can be solved using Greedy technique. Follow the steps below to solve the problem:

Below is the implementation of the above approach:




// C++ program to implement
// the above approach
 
#include <bits/stdc++.h>
using namespace std;
 
// Function to find the minimum count of
// elements required to be removed such
// that frequency of arr[i] equal to arr[i]
int min_elements(int arr[], int N)
{
    // Stores frequency of each
    // element of the array
    unordered_map<int, int> mp;
 
    // Traverse the array
    for (int i = 0; i < N; i++) {
 
        // Update frequency
        // of arr[i]
        mp[arr[i]]++;
    }
 
    // Stores minimum count of removals
    int cntMinRem = 0;
 
    // Traverse the map
    for (auto it : mp) {
 
        // Stores key value
        // of the map
        int i = it.first;
 
        // If frequency of i is
        // less than i
        if (mp[i] < i) {
 
            // Update cntMinRem
            cntMinRem += mp[i];
        }
 
        // If frequency of i is
        // greater than i
        else if (mp[i] > i) {
 
            // Update cntMinRem
            cntMinRem += (mp[i] - i);
        }
    }
 
    return cntMinRem;
}
 
// Driver Code
int main()
{
 
    int arr[] = { 2, 4, 1, 4, 2 };
 
    int N = sizeof(arr) / sizeof(arr[0]);
 
    cout << min_elements(arr, N);
    return 0;
}




// Java program to implement
// the above approach
import java.util.*;
 
class GFG{
     
// Function to find the minimum count of
// elements required to be removed such
// that frequency of arr[i] equal to arr[i]
public static int min_elements(int arr[], int N)
{
     
    // Stores frequency of each
    // element of the array
    Map<Integer,
        Integer> mp = new HashMap<Integer,
                                  Integer>();
 
    // Traverse the array
    for(int i = 0; i < N; i++)
    {
         
        // Update frequency
        // of arr[i]
        mp.put(arr[i],
               mp.getOrDefault(arr[i], 0) + 1);
    }
 
    // Stores minimum count of removals
    int cntMinRem = 0;
 
    // Traverse the map
    for(int key : mp.keySet())
    {
         
        // Stores key value
        // of the map
        int i = key;
        int val = mp.get(i);
 
        // If frequency of i is
        // less than i
        if (val < i)
        {
             
            // Update cntMinRem
            cntMinRem += val;
        }
 
        // If frequency of i is
        // greater than i
        else if (val > i)
        {
             
            // Update cntMinRem
            cntMinRem += (val - i);
        }
    }
    return cntMinRem;
}
 
// Driver Code
public static void main(String[] args)
{
    int arr[] = { 2, 4, 1, 4, 2 };
 
    System.out.println(min_elements(
        arr, arr.length));
}
}
 
// This code is contributed by grand_master




# Python3 program to implement
# the above approach
 
# Function to find the minimum count of
# elements required to be removed such
# that frequency of arr[i] equal to arr[i]
def min_elements(arr, N) :
     
    # Stores frequency of each
    # element of the array
    mp = {};
 
    # Traverse the array
    for i in range(N) :
 
        # Update frequency
        # of arr[i]
        if arr[i] in mp :
            mp[arr[i]] += 1;
        else :
            mp[arr[i]] = 1;
 
    # Stores minimum count of removals
    cntMinRem = 0;
 
    # Traverse the map
    for it in mp :
 
        # Stores key value
        # of the map
        i = it;
 
        # If frequency of i is
        # less than i
        if (mp[i] < i) :
 
            # Update cntMinRem
            cntMinRem += mp[i];
 
        # If frequency of i is
        # greater than i
        elif (mp[i] > i) :
 
            # Update cntMinRem
            cntMinRem += (mp[i] - i);
             
    return cntMinRem;
 
# Driver Code
if __name__ == "__main__" :
 
    arr = [ 2, 4, 1, 4, 2 ];
    N = len(arr);
    print(min_elements(arr, N));
     
    # This code is contributed by AnkThon




// C# program to implement
// the above approach
using System;
using System.Collections.Generic;
class GFG
{
     
    // Function to find the minimum count of
    // elements required to be removed such
    // that frequency of arr[i] equal to arr[i]
    static int min_elements(int[] arr, int N)
    {
       
        // Stores frequency of each
        // element of the array
        Dictionary<int, int> mp = new Dictionary<int, int>(); 
      
        // Traverse the array
        for (int i = 0; i < N; i++)
        {
      
            // Update frequency
            // of arr[i]
            if(mp.ContainsKey(arr[i]))
            {
                mp[arr[i]]++;
            }
            else
            {
                mp[arr[i]] = 1;
            }
        }
      
        // Stores minimum count of removals
        int cntMinRem = 0;
      
        // Traverse the map
        foreach (KeyValuePair<int, int> it in mp)
        {
      
            // Stores key value
            // of the map
            int i = it.Key;
      
            // If frequency of i is
            // less than i
            if (mp[i] < i)
            {
      
                // Update cntMinRem
                cntMinRem += mp[i];
            }
      
            // If frequency of i is
            // greater than i
            else if (mp[i] > i)
            {
      
                // Update cntMinRem
                cntMinRem += (mp[i] - i);
            }
        }    
        return cntMinRem;
    }
 
  // Driver code
  static void Main()
  {
    int[] arr = { 2, 4, 1, 4, 2 };
    int N = arr.Length;
    Console.Write(min_elements(arr, N));
  }
}
 
// This code is contributed by divyesh072019




<script>
 
// Javascript program to implement
// the above approach
 
// Function to find the minimum count of
// elements required to be removed such
// that frequency of arr[i] equal to arr[i]
function min_elements(arr, N)
{
    // Stores frequency of each
    // element of the array
    var mp = new Map();
 
    // Traverse the array
    for (var i = 0; i < N; i++) {
 
        // Update frequency
        // of arr[i]
        if(mp.has(arr[i]))
        {
            mp.set(arr[i], mp.get(arr[i])+1);
        }
        else
        {
            mp.set(arr[i], 1);
        }
    }
 
    // Stores minimum count of removals
    var cntMinRem = 0;
 
    // Traverse the map
    mp.forEach((value, key) => {
         
        // Stores key value
        // of the map
        var i = key;
 
        // If frequency of i is
        // less than i
        if (mp.get(i) < i) {
 
            // Update cntMinRem
            cntMinRem += mp.get(i);
        }
 
        // If frequency of i is
        // greater than i
        else if (mp.get(i) > i) {
 
            // Update cntMinRem
            cntMinRem += (mp.get(i) - i);
        }
    });
 
    return cntMinRem;
}
 
// Driver Code
var arr = [2, 4, 1, 4, 2];
var N = arr.length;
document.write( min_elements(arr, N));
 
</script>

Output: 
2

 

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

Approach 2: No Extra Space:

The above approach uses a unordered_map and has auxiliary space O(N).

Here is the optimized code:




#include <iostream>
using namespace std;
 
int min_elements(int arr[], int N) {
    // update the frequency of each element in the array
    for (int i = 0; i < N; i++) {
        arr[arr[i] % N] += N;
    }
 
    int cntMinRem = 0;
    // count the number of elements for which the frequency is less than or greater than the element value
    for (int i = 0; i < N; i++) {
        if (arr[i] / N < i) {
            cntMinRem += arr[i] / N;
        }
        if (arr[i] / N > i + 1) {
            cntMinRem += (arr[i] / N - i - 1);
        }
    }
 
    return cntMinRem;
}
 
int main() {
    int arr[] = { 2, 4, 1, 4, 2 };
    int N = sizeof(arr) / sizeof(arr[0]);
    cout << min_elements(arr, N);
    return 0;
}




/*package whatever //do not write package name here */
import java.util.*;
 
public class Main {
    public static int minElements(int[] arr, int N) {
        // update the frequency of each element in the array
        for (int i = 0; i < N; i++) {
            arr[arr[i] % N] += N;
        }
 
        int cntMinRem = 0;
        // count the number of elements for which the frequency
       // is less than or greater than the element value
        for (int i = 0; i < N; i++) {
            if (arr[i] / N < i) {
                cntMinRem += arr[i] / N;
            }
            if (arr[i] / N > i + 1) {
                cntMinRem += (arr[i] / N - i - 1);
            }
        }
 
        return cntMinRem;
    }
 
    public static void main(String[] args) {
        int[] arr = { 2, 4, 1, 4, 2 };
        int N = arr.length;
        System.out.println(minElements(arr, N));
    }
}




def min_elements(arr, N):
    # update the frequency of each element in the array
    for i in range(N):
        arr[arr[i] % N] += N
 
    cntMinRem = 0
    # count the number of elements for which the frequency is less than or greater than the element value
    for i in range(N):
        if arr[i] // N < i:
            cntMinRem += arr[i] // N
        if arr[i] // N > i + 1:
            cntMinRem += arr[i] // N - i - 1
 
    return cntMinRem
 
arr = [2, 4, 1, 4, 2]
N = len(arr)
print(min_elements(arr, N))




using System;
 
public class Program {
    public static int MinElements(int[] arr, int N)
    {
        // update the frequency of each element in the array
        for (int i = 0; i < N; i++) {
            arr[arr[i] % N] += N;
        }
        int cntMinRem = 0;
        // count the number of elements for which the
        // frequency is less than or greater than the
        // element value
        for (int i = 0; i < N; i++) {
            if (arr[i] / N < i) {
                cntMinRem += arr[i] / N;
            }
            if (arr[i] / N > i + 1) {
                cntMinRem += (arr[i] / N - i - 1);
            }
        }
 
        return cntMinRem;
    }
 
    public static void Main()
    {
        int[] arr = { 2, 4, 1, 4, 2 };
        int N = arr.Length;
        Console.WriteLine(MinElements(arr, N));
    }
}




function min_elements(arr, N) {
    // update the frequency of each element in the array
    for (let i = 0; i < N; i++) {
        arr[arr[i] % N] += N;
    }
 
    let cntMinRem = 0;
    // count the number of elements for which the
    // frequency is less than or greater than the element value
    for (let i = 0; i < N; i++) {
        if (arr[i] / N < i) {
            cntMinRem += Math.floor(arr[i] / N);
        }
        if (arr[i] / N > i + 1) {
            cntMinRem += Math.floor(arr[i] / N) - i - 1;
        }
    }
 
    return cntMinRem;
}
 
let arr = [2, 4, 1, 4, 2];
let N = arr.length;
console.log(min_elements(arr, N));

OUTPUT:

2

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


Article Tags :