Open In App

Minimum number of distinct elements after removing m items

Improve
Improve
Like Article
Like
Save
Share
Report

Given an array of items, an i-th 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
Remove 1 and both 2's.So, only 3 will be
left that's why distinct id is 1.
Input : arr[] = { 2, 4, 1, 5, 3, 5, 1, 3}
m = 2
Output : 3
Remove 2 and 4 completely. So, remaining ids
are 1, 3 and 5 i.e. 3

Asked in: Morgan Stanley

  1. Count the occurrence of elements and store them in the hash. 
  2. Sort the hash. 
  3. Start removing elements from the hash whose frequency count is less than m. 
  4. Return the number of values left in the hash.

Implementation:

C++




// C++ program for above implementation
#include <bits/stdc++.h>
using namespace std;
 
// Function to find distinct id's
int distinctIds(int arr[], int n, int mi)
{
    unordered_map<int, int> m;
    vector<pair<int, int> > v;
    int count = 0;
 
    // Store the occurrence of ids
    for (int i = 0; i < n; i++)
        m[arr[i]]++;
 
    // Store into the vector second as first and vice-versa
    for (auto it = m.begin(); it != m.end(); it++)
        v.push_back(make_pair(it->second, it->first));
 
    // Sort the vector
    sort(v.begin(), v.end());
 
    int size = v.size();
 
    // Start removing elements from the beginning
    for (int i = 0; i < size; i++) {
 
        // Remove if current value is less than
        // or equal to mi
        if (v[i].first <= mi) {
            mi -= v[i].first;
            count++;
        }
 
        // Return the remaining size
        else
            return size - count;
    }
    return size - count;
}
 
// Driver code
int main()
{
    int arr[] = { 2, 3, 1, 2, 3, 3 };
    int n = sizeof(arr) / sizeof(arr[0]);
 
    int m = 3;
 
    cout << distinctIds(arr, n, m);
    return 0;
}


Java




import java.util.*;
 
class Solution {
    static int distinctIds(int arr[], int n, int m)
    {
        // Creating HashMap to store frequency count
        HashMap<Integer, Integer> h = new HashMap<>();
 
        for (int i = 0; i < n; i++) {
            if (h.containsKey(arr[i])) {
                h.put(arr[i], h.get(arr[i]) + 1);
            }
            else {
                h.put(arr[i], 1);
            }
        }
 
        // Creating a list to sort HashMap according to
        // values
        List<Map.Entry<Integer, Integer> > l
            = new LinkedList<Map.Entry<Integer, Integer> >(
                h.entrySet());
 
        // sorting using Comparator
        Collections.sort(
            l,
            new Comparator<Map.Entry<Integer, Integer> >() {
                public int compare(
                    Map.Entry<Integer, Integer> o1,
                    Map.Entry<Integer, Integer> o2)
                {
                    return o1.getValue() - o2.getValue();
                }
            });
 
        // Creating new map after sorting and also
        // maintaining insertion order
        LinkedHashMap<Integer, Integer> lh
            = new LinkedHashMap<>();
        for (Map.Entry<Integer, Integer> e : l) {
            lh.put(e.getKey(), e.getValue());
        }
 
        for (Integer i : lh.keySet()) {
            // removing element from whose frequency count is
            // less than m ,Sorted manner to get minimum
            // distinct ids
            if (h.get(i) <= m) {
                m -= h.get(i);
                h.remove(i);
            }
        }
 
        return h.size();
    }
 
    public static void main(String[] args)
    {
        // TODO Auto-generated method stub
        int arr[] = { 2, 4, 1, 5, 3, 5, 1, 3 };
        int m = 2;
 
        System.out.println(distinctIds(arr, arr.length, m));
    }
}


Python3




# Python program for above implementation
 
# Function to find distinct id's
def distinctIds(arr, n, mi):
  m = {}
  v = []
  count = 0
 
  # Store the occurrence of ids
  for i in range(n):
    if arr[i] in m:
      m[arr[i]] += 1
    else:
      m[arr[i]] = 1
 
  # Store into the list value as key and vice-versa
  for i in m:
    v.append([m[i],i])
 
  v.sort()
  size = len(v)
 
  # Start removing elements from the beginning
  for i in range(size):
     
    # Remove if current value is less than
    # or equal to mi
    if (v[i][0] <= mi):
      mi -= v[i][0]
      count += 1
         
    else:   # Return the remaining size
      return size - count
  return size - count
 
# Driver code
arr = [ 2, 3, 1, 2, 3, 3 ]
n = len(arr)
 
m = 3
 
# To display the result
print(distinctIds(arr, n, m))
 
# This code is contributed by rohitsingh07052


C#




// C# program for Minimum number of
// distinct elements after removing m items
using System;
using System.Collections.Generic; 
class GFG
{
 
  // Function to find distinct id's
  static int distinctIds(int[] arr, int n, int mi)
  {
 
    Dictionary<int, int> m = new Dictionary<int, int>(); 
    int count = 0;
    int size = 0;
 
    // Store the occurrence of ids
    for (int i = 0; i < n; i++)
    {
 
      // If the key is not add it to map
      if (m.ContainsKey(arr[i]) == false)
      {
        m[arr[i]] = 1;
        size++;
      }
 
      // If it is present then increase the value by 1
      else
      {
        m[arr[i]]++;
      }
    }
 
    // Start removing elements from the beginning
    foreach(KeyValuePair<int, int> mp in m)
    {
 
      // Remove if current value is less than
      // or equal to mi
      if (mp.Key <= mi)
      {
        mi -= mp.Key;
        count++;
      }
    }
    return size - count;
  }
 
  // Driver code
  static void Main()
  {
 
    // TODO Auto-generated method stub
    int[] arr = {2, 3, 1, 2, 3, 3};
    int m = 3;
 
    Console.WriteLine(distinctIds(arr, arr.Length, m));
  }
}
 
// This code is contributed by divyeshrabadiya07


Javascript




<script>
 
// Javascript program for above implementation
 
// Function to find distinct id's
function distinctIds(arr, n, mi)
{
    var m = new Map();
    var v = [];
    var count = 0;
 
    // Store the occurrence of ids
    for (var i = 0; i < n; i++)
    {
        if(m.has(arr[i]))
            m.set(arr[i], m.get(arr[i])+1)
        else
            m.set(arr[i], 1)
    }
 
    // Store into the vector second as first and vice-versa
    m.forEach((value, key) => {
         
        v.push([value, key]);
    });
 
    // Sort the vector
    v.sort()
 
    var size = v.length;
 
    // Start removing elements from the beginning
    for (var i = 0; i < size; i++) {
 
        // Remove if current value is less than
        // or equal to mi
        if (v[i][0] <= mi) {
            mi -= v[i][0];
            count++;
        }
 
        // Return the remaining size
        else
            return size - count;
    }
    return size - count;
}
 
// Driver code
var arr = [2, 3, 1, 2, 3, 3 ];
var n = arr.length;
var m = 3;
document.write( distinctIds(arr, n, m));
 
// This code is contributed by immportantly.
</script>


Output

1






Time Complexity: O(n log n)

Space Complexity: O(n), As we are using map to store elements 

Approach 2: Using Priority Queue and Map

  1. Create a frequency map:
    An unordered map is created to store the frequency of each element in the given array. The key of the map is the element itself and the value is its frequency.
  2. Create a priority queue:
    A priority queue is created to store the frequency of the elements in ascending order. The priority queue is a min heap, which means that the smallest element will be at the top of the queue.
  3. Insert the frequency of each element into the priority queue:
    Iterate through the frequency map and insert the frequency of each element into the priority queue.
  4. Remove elements:
    Now, remove elements from the priority queue until k becomes less than or equal to zero. While removing an element from the queue, subtract its frequency from k. If k becomes negative, break the loop and return the size of the priority queue.
  5. Return the size of the priority queue:
    After removing k elements, return the size of the priority queue.

C++




// C++ program for above implementation
#include <bits/stdc++.h>
using namespace std;
 
// Function to find distinct id's
int distinctIds(int arr[], int n, int k)
{
    // Step 1: Create a frequency map of the elements in the
    // array
    unordered_map<int, int> mp;
    for (int i = 0; i < n; i++) {
        mp[arr[i]]++;
    }
 
    // Step 2: Create a priority queue to store the
    // frequencies in ascending order
    priority_queue<int, vector<int>, greater<int> > pq;
 
    // Step 3: Insert the frequencies of the elements into
    // the priority queue
    for (auto it : mp) {
        pq.push(it.second);
    }
 
    // Step 4: Remove elements from the priority queue until
    // k becomes less than or equal to 0
    while (k > 0) {
        k -= pq.top(); // Subtract the frequency of the
                       // smallest element from k
        if (k >= 0)
            pq.pop(); // Remove the smallest element from
                      // the queue if k is still positive
    }
 
    // Step 5: Return the size of the priority queue
    return pq.size();
}
// Driver code
int main()
{
    int arr[] = { 2, 3, 1, 2, 3, 3 };
    int n = sizeof(arr) / sizeof(arr[0]);
 
    int k = 3;
 
    cout << distinctIds(arr, n, k);
    return 0;
}
// this code is contributed by Ravi Singh


Java




import java.util.*;
 
class Solution {
    static int distinctIds(int[] arr, int n, int k)
    {
        // Step 1: Create a frequency map of the elements in
        // the array
        HashMap<Integer, Integer> map
            = new HashMap<Integer, Integer>();
        for (int num : arr) {
            map.put(num, map.getOrDefault(num, 0) + 1);
        }
 
        // Step 2: Create a priority queue to store the
        // frequencies in ascending order
        PriorityQueue<Integer> pq
            = new PriorityQueue<Integer>();
 
        // Step 3: Insert the frequencies of the elements
        // into the priority queue
        for (int freq : map.values()) {
            pq.offer(freq);
        }
 
        // Step 4: Remove elements from the priority queue
        // until k becomes less than or equal to 0
        while (k > 0 && !pq.isEmpty()) {
            k -= pq.poll(); // Subtract the frequency of the
                            // smallest element from k
        }
 
        // Step 5: Return the size of the priority queue
        return pq.size();
    }
 
    public static void main(String[] args)
    {
        // TODO Auto-generated method stub
        int arr[] = { 2, 4, 1, 5, 3, 5, 1, 3 };
        int m = 2;
 
        System.out.println(distinctIds(arr, arr.length, m));
    }
}
// this code is contributed by Ravi Singh


Python3




# Python program for above implementation
import heapq
 
# Function to find distinct id's
 
 
def distinctIds(arr, n, k):
    # Step 1: Create a frequency map of the elements in the array
    mp = {}
    for i in range(n):
        mp[arr[i]] = mp.get(arr[i], 0) + 1
 
    # Step 2: Create a priority queue to store the frequencies in ascending order
    pq = []
 
    # Step 3: Insert the frequencies of the elements into the priority queue
    for _, freq in mp.items():
        pq.append(freq)
 
    heapq.heapify(pq)  # heapify to get a min-heap
 
    # Step 4: Remove elements from the priority queue until k becomes less than or equal to 0
    while k > 0:
        # Subtract the frequency of the smallest element from k
        k -= heapq.heappop(pq)
        if k >= 0 and not pq:  # if k is still positive and the priority queue is empty, return -1
            return -1
 
    # Step 5: Return the size of the priority queue
    return len(pq)
 
 
# Driver code
if __name__ == '__main__':
    arr = [2, 3, 1, 2, 3, 3]
    n = len(arr)
    k = 3
    print(distinctIds(arr, n, k))
 
# This code is contributed by rishabmalhdijo


C#




using System;
using System.Collections.Generic;
 
class GFG {
    // Function to find distinct id's
    static int distinctIds(int[] arr, int n, int k)
    {
        // Step 1: Create a frequency map of the elements in
        // the array
        Dictionary<int, int> mp
            = new Dictionary<int, int>();
        for (int i = 0; i < n; i++) {
            if (mp.ContainsKey(arr[i]))
                mp[arr[i]]++;
            else
                mp[arr[i]] = 1;
        }
 
        // Step 2: Create a list to store the frequencies in
        // ascending order
        List<int> pq = new List<int>();
        foreach(KeyValuePair<int, int> entry in mp)
            pq.Add(entry.Value);
 
        // Step 3: Sort the list to get a min-heap
        pq.Sort();
 
        // Step 4: Remove elements from the list until k
        // becomes less than or equal to 0
        int ans = 0;
        while (pq.Count > 0 && k >= pq[0]) {
            k -= pq[0]; // Subtract the frequency of the
                        // smallest element from k
            ans++; // Increment the count of distinct id's
            pq.RemoveAt(0); // Remove the smallest element
                            // from the list
        }
 
        if (pq.Count == 0
            && k > 0) // If k is still positive and the list
                      // is empty, return -1
            return -1;
 
        // Step 5: Return the size of the list
        return pq.Count;
    }
 
    // Driver code
    public static void Main()
    {
        int[] arr = { 2, 3, 1, 2, 3, 3 };
        int n = arr.Length;
        int k = 3;
        Console.WriteLine(distinctIds(arr, n, k));
    }
}


Javascript




// Javascript code addition
 
 
// PriorityQueue implementation in JavaScript
class PriorityQueue {
  constructor(compareFunc) {
    this.heap = [];
    this.compare = compareFunc || ((a, b) => a - b);
  }
 
  enqueue(val) {
    this.heap.push(val);
    this.bubbleUp();
  }
 
  dequeue() {
    if (this.isEmpty()) {
      throw new Error('Queue is empty');
    }
 
    const max = this.peek();
    const last = this.heap.pop();
    if (this.size() > 0) {
      this.heap[0] = last;
      this.bubbleDown();
    }
    return max;
  }
 
  peek() {
    if (this.isEmpty()) {
      throw new Error('Queue is empty');
    }
    return this.heap[0];
  }
 
  size() {
    return this.heap.length;
  }
 
  isEmpty() {
    return this.size() === 0;
  }
 
  bubbleUp() {
    let index = this.size() - 1;
    while (index > 0) {
      const parentIndex = Math.floor((index - 1) / 2);
      if (this.compare(this.heap[index], this.heap[parentIndex]) >= 0) {
        break;
      }
      [this.heap[parentIndex], this.heap[index]] = [
        this.heap[index],
        this.heap[parentIndex],
      ];
      index = parentIndex;
    }
  }
 
  bubbleDown() {
    let index = 0;
    const lastIndex = this.size() - 1;
    while (true) {
      const leftChildIndex = index * 2 + 1;
      const rightChildIndex = index * 2 + 2;
      let minChildIndex = null;
 
      if (leftChildIndex <= lastIndex) {
        minChildIndex = leftChildIndex;
      }
 
      if (rightChildIndex <= lastIndex && this.compare(this.heap[rightChildIndex], this.heap[leftChildIndex]) < 0) {
        minChildIndex = rightChildIndex;
      }
 
      if (minChildIndex === null || this.compare(this.heap[index], this.heap[minChildIndex]) <= 0) {
        break;
      }
 
      [this.heap[index], this.heap[minChildIndex]] = [
        this.heap[minChildIndex],
        this.heap[index],
      ];
      index = minChildIndex;
    }
  }
}
 
 
// Function to find distinct id's
function distinctIds(arr, n, k) {
  // Step 1: Create a frequency map of the elements in the array
  let mp = new Map();
  for (let i = 0; i < n; i++) {
    mp.set(arr[i], (mp.get(arr[i]) || 0) + 1);
  }
 
  // Step 2: Create a priority queue to store the frequencies in ascending order
  let pq = new PriorityQueue((a, b) => a - b);
 
  // Step 3: Insert the frequencies of the elements into the priority queue
  for (let [key, val] of mp.entries()) {
    pq.enqueue(val);
  }
 
  // Step 4: Remove elements from the priority queue until k becomes less than or equal to 0
  while (k > 0 && !pq.isEmpty()) {
    k -= pq.dequeue(); // Subtract the frequency of the smallest element from k
  }
 
  // Step 5: Return the size of the priority queue
  return pq.size();
}
 
 
// Driver code
const arr = [2, 3, 1, 2, 3, 3];
const n = arr.length;
const k = 3;
 
console.log(distinctIds(arr, n, k)); // Output
 
// The code is contributed by Nidhi goel.


Output

1






Time Complexity: O(n log n)

Space Complexity: O(n)

This article is contributed by Sahil Chhabra.  

METHOD 3:Using counter method .

APPROACH:

This program finds the minimum number of distinct elements in a list after removing m items from it.

ALGORITHM:

1.Create a Counter object from the input list to get the frequency of each element.
2.Get the total number of distinct elements in the list by getting the length of the Counter object.
3.Iterate over the items of the Counter object and remove the elements that have a frequency less than or equal to m.
4.Return the updated count of distinct elements.

C++




#include <iostream>
#include <unordered_map>
#include <vector>
 
int minDistinctElements(std::vector<int>& arr, int m) {
    // Create an unordered_map to store the frequency of each element in the array.
    std::unordered_map<int, int> freq;
 
    // Calculate the frequency of each element in the array.
    for (int num : arr) {
        freq[num]++;
    }
 
    // Initialize a variable to count the distinct elements.
    int distinct = freq.size();
 
    // Iterate through the elements and their frequencies.
    for (const auto& entry : freq) {
        int v = entry.second;
 
        // If the remaining removals (m) are greater than or equal to the frequency (v),
        // we can remove all occurrences of this element.
        if (v <= m) {
            m -= v;
        } else {
            // If the remaining removals are less than the frequency, we reduce the frequency.
            distinct -= 1;
            m -= 1;
        }
    }
 
    return distinct;
}
 
int main() {
    std::vector<int> arr = {2, 2, 1, 3, 3, 3};
    int m = 3;
    int result = minDistinctElements(arr, m);
    std::cout << result << std::endl; // Output: 1
    return 0;
}
 
 
// This code is contributed by akshitaguprzj3


Java




import java.util.HashMap;
import java.util.Map;
 
public class Main {
    public static int minDistinctElements(int[] arr, int m) {
        // Create a HashMap to store the frequency of each element in the array.
        Map<Integer, Integer> freq = new HashMap<>();
         
        // Calculate the frequency of each element in the array.
        for (int num : arr) {
            freq.put(num, freq.getOrDefault(num, 0) + 1);
        }
         
        // Initialize a variable to count the distinct elements.
        int distinct = freq.size();
         
        // Iterate through the elements and their frequencies.
        for (Map.Entry<Integer, Integer> entry : freq.entrySet()) {
            int v = entry.getValue();
             
            // If the remaining removals (m) are greater than or equal to the frequency (v),
            // we can remove all occurrences of this element.
            if (v <= m) {
                distinct--;
                m -= v;
            } else {
                // If the remaining removals are less than the frequency, break the loop.
                break;
            }
        }
         
        return distinct;
    }
 
    public static void main(String[] args) {
        int[] arr = {2, 2, 1, 3, 3, 3};
        int m = 3;
        int result = minDistinctElements(arr, m);
        System.out.println(result); // Output: 1
    }
}
 
// This code is contributed by shivamgupta0987654321


Python3




from collections import Counter
 
def min_distinct_elements(arr, m):
    freq = Counter(arr)
    distinct = len(freq)
    for k, v in freq.items():
        if v <= m:
            distinct -= 1
            m -= v
        else:
            break
    return distinct
 
# Example usage:
arr = [2, 2, 1, 3, 3, 3]
m = 3
result = min_distinct_elements(arr, m)
print(result)  # Output: 1


C#




using System;
using System.Collections.Generic;
 
class Program
{
    static int MinDistinctElements(int[] arr, int m)
    {
        // Create a Dictionary to store the frequency of each element in the array.
        Dictionary<int, int> freq = new Dictionary<int, int>();
 
        // Calculate the frequency of each element in the array.
        foreach (int num in arr)
        {
            if (freq.ContainsKey(num))
                freq[num]++;
            else
                freq[num] = 1;
        }
 
        // Initialize a variable to count the distinct elements.
        int distinct = freq.Count;
 
        // Iterate through the elements and their frequencies.
        foreach (var entry in freq)
        {
            int v = entry.Value;
 
            // If the remaining removals (m) are greater than or equal to the frequency (v),
            // we can remove all occurrences of this element.
            if (v <= m)
            {
                distinct--;
                m -= v;
            }
            else
            {
                // If the remaining removals are less than the frequency, break the loop.
                break;
            }
        }
 
        return distinct;
    }
 
    static void Main(string[] args)
    {
        int[] arr = { 2, 2, 1, 3, 3, 3 };
        int m = 3;
        int result = MinDistinctElements(arr, m);
        Console.WriteLine(result); // Output: 1
    }
}


Javascript




function minDistinctElements(arr, m) {
    // Create an object to store the frequency of each element in the array.
    const freq = {};
 
    // Calculate the frequency of each element in the array.
    for (const num of arr) {
        freq[num] = (freq[num] || 0) + 1;
    }
 
    // Initialize a variable to count the distinct elements.
    let distinct = Object.keys(freq).length;
 
    // Iterate through the elements and their frequencies.
    for (const key in freq) {
        if (freq.hasOwnProperty(key)) {
            const v = freq[key];
 
            // If the remaining removals (m) are greater than or equal to the frequency (v),
            // we can remove all occurrences of this element.
            if (v <= m) {
                distinct--;
                m -= v;
            } else {
                // If the remaining removals are less than the frequency, break the loop.
                break;
            }
        }
    }
 
    return distinct;
}
 
const arr = [2, 2, 1, 3, 3, 3];
const m = 3;
const result = minDistinctElements(arr, m);
console.log(result); // Output: 1


Output

1







Time complexity: O(n log n), where n is the length of the input list. This is because creating a Counter object has a time complexity of O(n log n) due to the underlying hash table operations.

Space complexity: O(n), where n is the length of the input list. This is because we need to store the frequency of each element in the Counter object.



Last Updated : 09 Nov, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads