Minimum number of distinct elements after removing m items
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
- Count the occurrence of elements and store them in the hash.
- Sort the hash.
- Start removing elements from the hash whose frequency count is less than m.
- 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
- 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. - 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. - 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. - 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. - 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 : k - = heapq.heappop(pq) # Subtract the frequency of the smallest element from k 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 |
Output
1
Time Complexity: O(n log n)
Space Complexity: O(n)
This article is contributed by Sahil Chhabra. If you like GeeksforGeeks and would like to contribute, you can also write an article using write.geeksforgeeks.org or mail your article to review-team@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.
Please Login to comment...