Minimum number of distinct elements after removing M items | Set 2
Given an array of items, an ith index element denotes the item id’s, and given a number m, the task is to remove m elements such that there should be minimum distinct id’s left. Print the number of distinct id’s.
Examples:
Input: arr[] = { 2, 2, 1, 3, 3, 3} m = 3
Output: 1
Explanation:
Remove 1 and both 2’s.
So, only 3 will be left, hence distinct number of element is 1.
Input: arr[] = { 2, 4, 1, 5, 3, 5, 1, 3} m = 2
Output: 3
Explanation:
Remove 2 and 4 completely.
So, remaining 1, 3 and 5 i.e. 3 elements.
For O(N*log N) approach please refer to the previous article.
Efficient Approach: The idea is to store the occurrence of each element in a Hash and count the occurrence of each frequency in a hash again. Below are the steps:
- Traverse the given array elements and count the occurrences of each number and store it into the hash.
- Now instead of sorting the frequency, count the occurrences of the frequency into another array say fre_arr[].
- Calculate the total unique numbers(say ans) as the number of distinct id’s.
- Now, traverse the freq_arr[] array and if freq_arr[i] > 0 then remove the minimum of m/i and freq_arr[i](say t) from ans and subtract i*t from m to remove the occurrence of any number i from m.
Below is the implementation of the above approach.
C++
#include <bits/stdc++.h>
using namespace std;
int distinctNumbers( int arr[], int m,
int n)
{
unordered_map< int , int > count;
for ( int i = 0; i < n; i++)
count[arr[i]]++;
vector< int > fre_arr(n + 1, 0);
for ( auto it : count) {
fre_arr[it.second]++;
}
int ans = count.size();
for ( int i = 1; i <= n; i++) {
int temp = fre_arr[i];
if (temp == 0)
continue ;
int t = min(temp, m / i);
ans -= t;
m -= i * t;
}
return ans;
}
int main()
{
int arr[] = { 2, 4, 1, 5, 3, 5, 1, 3 };
int n = sizeof (arr) / sizeof (arr[0]);
int m = 2;
cout << distinctNumbers(arr, m, n);
return 0;
}
|
Java
import java.util.*;
class GFG{
static int distinctNumbers( int arr[], int m,
int n)
{
Map<Integer,
Integer> count = new HashMap<Integer,
Integer>();
for ( int i = 0 ; i < n; i++)
count.put(arr[i],
count.getOrDefault(arr[i], 0 ) + 1 );
int [] fre_arr = new int [n + 1 ];
for (Integer it : count.values())
{
fre_arr[it]++;
}
int ans = count.size();
for ( int i = 1 ; i <= n; i++)
{
int temp = fre_arr[i];
if (temp == 0 )
continue ;
int t = Math.min(temp, m / i);
ans -= t;
m -= i * t;
}
return ans;
}
public static void main(String[] args)
{
int arr[] = { 2 , 4 , 1 , 5 , 3 , 5 , 1 , 3 };
int n = arr.length;
int m = 2 ;
System.out.println(distinctNumbers(arr, m, n));
}
}
|
Python3
def distinctNumbers(arr, m, n):
count = {}
for i in range (n):
count[arr[i]] = count.get(arr[i], 0 ) + 1
fre_arr = [ 0 ] * (n + 1 )
for it in count:
fre_arr[count[it]] + = 1
ans = len (count)
for i in range ( 1 , n + 1 ):
temp = fre_arr[i]
if (temp = = 0 ):
continue
t = min (temp, m / / i)
ans - = t
m - = i * t
return ans
if __name__ = = '__main__' :
arr = [ 2 , 4 , 1 , 5 , 3 , 5 , 1 , 3 ]
n = len (arr)
m = 2
print (distinctNumbers(arr, m, n))
|
C#
using System;
using System.Collections.Generic;
class GFG{
static int distinctNumbers( int []arr,
int m, int n)
{
Dictionary< int ,
int > count = new Dictionary< int ,
int >();
for ( int i = 0; i < n; i++)
if (count.ContainsKey(arr[i]))
{
count[arr[i]] = count[arr[i]] + 1;
}
else
{
count.Add(arr[i], 1);
}
int [] fre_arr = new int [n + 1];
foreach ( int it in count.Values)
{
fre_arr[it]++;
}
int ans = count.Count;
for ( int i = 1; i <= n; i++)
{
int temp = fre_arr[i];
if (temp == 0)
continue ;
int t = Math.Min(temp, m / i);
ans -= t;
m -= i * t;
}
return ans;
}
public static void Main(String[] args)
{
int []arr = {2, 4, 1, 5, 3, 5, 1, 3};
int n = arr.Length;
int m = 2;
Console.WriteLine(distinctNumbers(arr, m, n));
}
}
|
Javascript
<script>
function distinctNumbers(arr, m, n)
{
var count = new Map();
for ( var i = 0; i < n; i++)
if (count.has(arr[i]))
count.set(arr[i], count.get(arr[i])+1)
else
count.set(arr[i], 1)
var fre_arr = Array(n + 1).fill(0);
count.forEach((value, key) => {
fre_arr[value]++;
});
var ans = count.size;
for ( var i = 1; i <= n; i++) {
var temp = fre_arr[i];
if (temp == 0)
continue ;
var t = Math.min(temp, parseInt(m / i));
ans -= t;
m -= i * t;
}
return ans;
}
var arr = [2, 4, 1, 5, 3, 5, 1, 3];
var n = arr.length;
var m = 2;
document.write( distinctNumbers(arr, m, n));
</script>
|
Time Complexity: O(N)
Auxiliary Space: O(N)
Last Updated :
03 Jun, 2022
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...