Open In App

Minimize deletions in Array by deleting all occurrences of any number such that array size is reduced to at least half

Last Updated : 16 Feb, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Given an array arr[] of positive integers, the task is to select an element from the array and delete all its occurrences, such that the number of elements selected are minimum and the array size becomes atleast half of its original size.
Note: Size of the given array is always even.

Example:

Input: arr[] = {2, 2, 2, 2, 4, 4, 6, 7, 7, 3, 3, 3}
Output: 2
Explanation: First we select 2 and delete all its occurrences after that arr[] becomes – {4, 4, 6, 7, 7, 3, 3, 3} with size = 8. As the size is still greater than half, we select 3 and delete all its occurrences, after that arr[] becomes – {4, 4, 6, 7, 7} with size = 5.

Input: arr[] = {3, 3, 3, 3, 3}
Output: 1
Explanation : select 3 and remove all its occurrences.

Input: arr[] = {1, 2, 3, 4, 5, 6, 7, 8}
Output: 4
Explanation : Since there is no duplicate elements, hence any 4 elements can be removed to make the array length at least half.

 

Approach: The task can be easily achieved by removing the elements with maximum frequency, as soon as the array size becomes at least half of the actual size, we return the number of unique elements deleted till now.

Follow the steps to solve the problem:

  • Use Hash-map to store frequency of the elements in array present.
  • Store the frequencies in a list.
  • Sort the list and traverse it from the back.
  • Select the largest frequency element and decrement it from the array size and increment the count of unique elements deleted.
  • If new array size becomes at-least half of the original array size, return the number of unique elements till now.

Below is the implementation of the above approach:

C++




// C++ Program to implement
// the above approach
#include <bits/stdc++.h>
using namespace std;
 
 
    // Function to calculate the minimum
    // elements removed
     int reduceArrSize(int arr[],int n)
    {
        unordered_map<int,int> hm;
 
        // Making frequency map of elements
        for (int i = 0; i < n; i++) {
            hm[arr[i]]++;
        }
 
        // Storing frequencies in a list
        vector<int> freq;
 
        for(auto it = hm.begin(); it != hm.end(); it++)
        {
            freq.push_back(it->second);
        }
 
        // Sorting the list
        sort(freq.begin(), freq.end());
 
        int size = n;
        int idx = freq.size() - 1;
        int count = 0;
 
        // Counting number of elements to be deleted
        while (size > n/ 2) {
            size -= freq[idx--];
            count++;
        }
        return count;
    }
 
    // Driver Code
    int main()
    {
        int arr[] = { 2, 2, 2, 2, 4, 4,
                      6, 7, 7, 3, 3, 3 };
        int n = sizeof(arr)/sizeof(arr[0]);
        int count = reduceArrSize(arr, n);
        cout<<(count);
        return 0;
    }
 
// This code is contributed by Potta Lokesh


Java




// Java program for the above approach
import java.util.*;
 
class GFG {
 
    // Function to calculate the minimum
    // elements removed
    public static int reduceArrSize(int[] arr)
    {
        HashMap<Integer, Integer> hm = new HashMap<>();
 
        // Making frequency map of elements
        for (int i = 0; i < arr.length; i++) {
            hm.put(arr[i], hm.getOrDefault(arr[i], 0) + 1);
        }
 
        // Storing frequencies in a list
        ArrayList<Integer> freq
            = new ArrayList<Integer>(hm.values());
 
        // Sorting the list
        Collections.sort(freq);
 
        int size = arr.length;
        int idx = freq.size() - 1;
        int count = 0;
 
        // Counting number of elements to be deleted
        while (size > arr.length / 2) {
            size -= freq[idx--];
            count++;
        }
        return count;
    }
 
    // Driver Code
    public static void main(String[] args)
    {
        int[] arr = { 2, 2, 2, 2, 4, 4,
                      6, 7, 7, 3, 3, 3 };
        int count = reduceArrSize(arr);
        System.out.println(count);
    }
}


Python3




# python 3 Program to implement
# the above approach
 
# Function to calculate the minimum
# elements removed
def reduceArrSize(arr,n):
    hm = {}
 
    # Making frequency map of elements
    for i in range(n):
        if arr[i] in hm:
            hm[arr[i]] += 1
        else:
            hm[arr[i]] = 1
 
    # Storing frequencies in a list
    freq = []
 
    for key,value in hm.items():
        freq.append(value)
 
    # Sorting the list
    freq.sort()
 
    size = n
    idx = len(freq) - 1
    count = 0
 
    # Counting number of elements to be deleted
    while (size > n// 2):
        size -= freq[idx]
        idx -= 1
        count += 1
    return count
 
# Driver Code
if __name__ == '__main__':
    arr = [2, 2, 2, 2, 4, 4,6, 7, 7, 3, 3, 3]
    n = len(arr)
    count = reduceArrSize(arr, n)
    print(count)
     
    # This code is contributed by SURENDRA_GANGWAR.


C#




// C# program for the above approach
using System;
using System.Collections.Generic;
 
public class GFG {
 
    // Function to calculate the minimum
    // elements removed
    public static int reduceArrSize(int[] arr)
    {
        Dictionary<int, int> hm = new Dictionary<int, int>();
 
        // Making frequency map of elements
        for (int i = 0; i < arr.Length; i++) {
            if(hm.ContainsKey(arr[i])){
                hm[arr[i]] = hm[arr[i]]+1;
            }
            else{
                hm.Add(arr[i], 1);
            }
        }
 
        // Storing frequencies in a list
        List<int> freq
            = new List<int>(hm.Values);
 
        // Sorting the list
        freq.Sort();
 
        int size = arr.Length;
        int idx = freq.Count - 1;
        int count = 0;
 
        // Counting number of elements to be deleted
        while (size > arr.Length / 2) {
            size -= freq[idx--];
            count++;
        }
        return count;
    }
 
    // Driver Code
    public static void Main(String[] args)
    {
        int[] arr = { 2, 2, 2, 2, 4, 4,
                      6, 7, 7, 3, 3, 3 };
        int count = reduceArrSize(arr);
        Console.WriteLine(count);
    }
}
 
// This code is contributed by 29AjayKumar


Javascript




<script>
 
// Javascript program for the above approach
// Function to calculate the minimum
// elements removed
function reduceArrSize(arr)
{
    var hm = new Map();
     
    // Making frequency map of elements
    for (var i = 0; i < arr.length; i++) {
        if(hm.has(arr[i])){
            hm.set(arr[i], hm.get(arr[i])+1);
        }
        else{
            hm.set(arr[i], 1);
        }
    }
     
    // Storing frequencies in a list
    var freq =[ ...hm.values()];
     
    // Sorting the list
    freq.sort();
     
    var size = arr.length;
    var idx = freq.length - 1;
    var count = 0;
     
    // Counting number of elements to be deleted
    while (size > arr.length / 2) {
        size -= freq[idx--];
        count++;
    }
    return count;
}
 
// Driver Code
var arr = [2, 2, 2, 2, 4, 4,
              6, 7, 7, 3, 3, 3];
var count = reduceArrSize(arr);
document.write(count);
 
// This code is contributed by rutvik_56.
</script>


Output: 

2

 

Time Complexity: O(N*logN), sorting the frequency list
Auxiliary Space: O(N), hashmap to store the frequencies

Another efficient approach(Using a Priority Queue):

We can solve the problem by using a priority queue instead of sorting the frequency of elements. So we initialize a priority queue and store the frequency of every unique element which we get from an unordered map. Then we run a while loop and start deleting the elements from the priority queue which has the highest frequency to the lowest frequencies in decreasing order and hence we get the count of elements to be deleted. The time complexity of this approach is O(n*logn) but it will take very less time if elements are more frequent.

Below is the implementation of the above approach:

C++




// C++ Program to implement the above approach
#include <bits/stdc++.h>
using namespace std;
 
// Function to calculate the minimum
// elements removed
int reduceArrSize(int arr[],int n)
    {
        unordered_map<int,int> hm;
 
        // Making frequency map of elements
        for (int i = 0; i < n; i++) {
            hm[arr[i]]++;
        }
         
        priority_queue<int> pq;
 
        for(auto it = hm.begin(); it != hm.end(); it++)
        {
            pq.push(it->second);
        }
 
        int size = n;
        int count = 0;
 
        // Counting number of elements to be deleted
        while (size > n/ 2) {
            size -= pq.top();
            pq.pop();
            count++;
        }
        return count;
    }
 
// Driver Code
int main()
    {
        int arr[] = { 2, 2, 2, 2, 4, 4, 6, 7, 7, 3, 3, 3 };
        int n = sizeof(arr)/sizeof(arr[0]);
        int count = reduceArrSize(arr, n);
        cout<<(count);
        return 0;
    }
 
// This code is contributed by Pushpesh raj


Java




// Java Program to implement the above approach
import java.util.*;
 
public class Main {
 
    // Function to calculate the minimum
    // elements removed
    public static int reduceArrSize(int[] arr) {
        Map<Integer, Integer> hm = new HashMap<>();
 
        // Making frequency map of elements
        for (int i = 0; i < arr.length; i++) {
            hm.put(arr[i], hm.getOrDefault(arr[i], 0) + 1);
        }
 
        PriorityQueue<Integer> pq = new PriorityQueue<>(new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return o2 - o1;
            }
        });
 
        for (Map.Entry<Integer, Integer> entry : hm.entrySet()) {
            pq.add(entry.getValue());
        }
 
        int size = arr.length;
        int count = 0;
 
        // Counting number of elements to be deleted
        while (size > arr.length / 2) {
            size -= pq.poll();
            count++;
        }
        return count;
    }
 
    public static void main(String[] args) {
        int[] arr = { 2, 2, 2, 2, 4, 4, 6, 7, 7, 3, 3, 3 };
        int count = reduceArrSize(arr);
        System.out.println(count);
    }
}


C#




// C# code to implement the approach
using System;
using System.Collections.Generic;
 
class GFG {
 
  // Function to calculate the minimum
  // elements removed
  public static int ReduceArrSize(int[] arr)
  {
    Dictionary<int, int> hm
      = new Dictionary<int, int>();
 
    // Making frequency map of elements
    for (int i = 0; i < arr.Length; i++) {
      if (hm.ContainsKey(arr[i])) {
        hm[arr[i]]++;
      }
      else {
        hm.Add(arr[i], 1);
      }
    }
 
    // Declaring a sorted set
    SortedSet<int> pq = new SortedSet<int>(
      Comparer<int>.Create((o1, o2) => o2 - o1));
 
    // Building the sorted set
    foreach(KeyValuePair<int, int> entry in hm)
    {
      pq.Add(entry.Value);
    }
 
    int size = arr.Length;
    int count = 0;
 
    // Counting number of elements to be deleted
    while (size > arr.Length / 2) {
      size -= pq.Min;
      pq.Remove(pq.Min);
      count++;
    }
    return count;
  }
 
  // Driver code
  public static void Main(string[] args)
  {
    int[] arr = { 2, 2, 2, 2, 4, 4, 6, 7, 7, 3, 3, 3 };
 
    // Function call
    int count = ReduceArrSize(arr);
    Console.WriteLine(count);
  }
}
 
// This code is contributed by phasing17


Javascript




// JavaScript Program to implement the above approach
 
// Function to calculate the minimum
// elements removed
function reduceArrSize(arr, n) {
    let hm = new Map();
 
    // Making frequency map of elements
    for (let i = 0; i < n; i++) {
        if (hm.has(arr[i])) {
            hm.set(arr[i], hm.get(arr[i]) + 1);
        } else {
            hm.set(arr[i], 1);
        }
    }
 
    let pq = [];
 
    for (let [key, value] of hm) {
        pq.push(value);
    }
 
    pq.sort((a, b) => b - a);
 
    let size = n;
    let count = 0;
 
    // Counting number of elements to be deleted
    while (size > n / 2) {
        size -= pq.shift();
        count++;
    }
    return count;
}
 
// Driver Code
let arr = [2, 2, 2, 2, 4, 4, 6, 7, 7, 3, 3, 3];
let n = arr.length;
let count = reduceArrSize(arr, n);
console.log(count);
 
// This code is contributed by phasing17.


Python3




import heapq
import collections
   
    #Function to calculate the minimum elements removed
     
def reduceArrSize(arr):
   
    # Creating frequency map of elements
    hm = collections.Counter(arr)
     
    pq = []
 
    # Adding frequency of each element to priority queue
    for frequency in hm.values():
        heapq.heappush(pq, frequency)
 
    size = len(arr)
    count = 0
 
    # Counting number of elements to be deleted
    while size > len(arr)/2:
        size -= heapq.heappop(pq)
        count += 1
    return count//2
 
# Driver code
if __name__ == "__main__":
    arr = [ 2, 2, 2, 2, 4, 4, 6, 7, 7, 3, 3, 3 ]
    count = reduceArrSize(arr)
    print(count)


Output

2

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



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads