Open In App

Maximum distinct elements after removing k elements

Last Updated : 22 Jan, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Given an array arr[] containing n elements. The problem is to find the maximum number of distinct elements (non-repeating) after removing k elements from the array. 
Note: 1 <= k <= n.
Examples: 

Input : arr[] = {5, 7, 5, 5, 1, 2, 2}, k = 3
Output : 4
Remove 2 occurrences of element 5 and
1 occurrence of element 2.

Input : arr[] = {1, 2, 3, 4, 5, 6, 7}, k = 5
Output : 2

Input : arr[] = {1, 2, 2, 2}, k = 1
Output : 1

Approach: Following are the steps: 

  • Make a multi set from the given array.
  • During making this multiset check if the current element is present or not in multiset, if it is already present then simply reduce the k value and do not insert in the multiset.
  • If k becomes 0 then simply just put values in multiset.
  • After traversing the whole given array, 
    • If k is not equal to zero then it means the multiset is consist of only unique elements and we have to remove any of the k elements from the multiset to make k=0, so in this case the answer will be size of multiset minus k value at that time.
    • If k is equal to zero then it means there may be duplicate values present in the multiset so put all the values in a set and the size of this set will be the number of distinct elements after removing k elements

Below is the implementation of the above approach:

C++




// CPP implementation of the above approach
#include <bits/stdc++.h>
using namespace std;
   
// function to find maximum distinct elements
// after removing k elements
int maxDistinctNum(int a[], int n, int k)
{
  int i;
  multiset<int> s;
  // making multiset from given array
        for(i=0;i<n;i++){
            if(s.find(a[i])==s.end()||k==0)
            s.insert(a[i]);
            else
            {
                k--;
            }
        }
   
        if(k!=0)
        return s.size()-k;
        else{
            set<int> st;
            for(auto it:s){
                st.insert(it);
            }
            return st.size();
        }
}
 
// Driver Code
int main()
{
    int arr[] = { 5, 7, 5, 5, 1, 2, 2 };
    int n = sizeof(arr) / sizeof(arr[0]);
    int k = 3;
   
    // Function Call
    cout << "Maximum distinct elements = "
         << maxDistinctNum(arr, n, k);
    return 0;
}


Java




// Java implementation of the
// above approach
import java.util.*;
class GFG {
 
    // Function to find maximum
    // distinct elements after
    // removing k elements
    static int maxDistinctNum(int arr[], int n, int k)
    {
        HashMap<Integer, Integer> numToFreq
            = new HashMap<>();
 
        // Build frequency map
        for (int i = 0; i < n; i++) {
            numToFreq.put(arr[i],
                          numToFreq.getOrDefault(arr[i], 0)
                              + 1);
        }
 
        int result = 0;
 
        // Min-heap
        PriorityQueue<Integer> minHeap
            = new PriorityQueue<Integer>();
 
        // Add all number with freq=1 to
        // result and push others to minHeap
        for (Map.Entry<Integer, Integer> p :
             numToFreq.entrySet()) {
            if (p.getValue() == 1)
                ++result;
            else
                minHeap.add(p.getValue());
        }
 
        // Perform k operations
        while (k != 0 && !minHeap.isEmpty()) {
            // Pop the top() element
            Integer t = minHeap.poll();
 
            // Increment Result
            if (t == 1) {
                ++result;
            }
 
            // Reduce t and k
            // Push it again
            else {
                --t;
                --k;
                minHeap.add(t);
            }
        }
 
        // Return result
        return result;
    }
 
    // Driver code
    public static void main(String[] args)
    {
        int arr[] = { 5, 7, 5, 5, 1, 2, 2 };
        int n = arr.length;
        int k = 3;
 
        // Function Call
        System.out.println("Maximum distinct elements = "
                           + maxDistinctNum(arr, n, k));
    }
}
 
// This code is contributed by rutvik_56


Python3




# Python implementation of the above approach
 
# function to find maximum distinct elements after removing k elements
def maxDistinctNum(a, n, k):
   
   # making multiset from given array multisets are like dictionaries ,
   # so will initialise a dictionary
    s = {}
    for i in range(n):
        if a[i] not in s or k == 0:
            s[a[i]] = s.get(a[i], 0)+1
        else:
            s[a[i]] = 1
            k -= 1
    if k != 0:
        return len(s)-k
    else:
 
        st = set()
        for i in s:
            st.add(i)
        return len(st)
 
# Driver Code
if __name__ == "__main__":
 
  # Array
    arr = [5, 7, 5, 5, 1, 2, 2]
    K = 3
 
    # Size of array
    N = len(arr)
     
    # Function Call
    print("Maximum distinct elements = ", maxDistinctNum(arr, N, K))
 
# This code is contributed by vivekmaddheshiya205


C#




using System;
using System.Linq;
using System.Collections.Generic;
 
class MainClass {
    public static int maxDistinctNum(int[] a, int n, int k) {
        HashSet<int> s = new HashSet<int>();
        for(int i=0;i<n;i++){
            if(!s.Contains(a[i]) || k==0)
            s.Add(a[i]);
            else
            {
                k--;
            }
        }
 
        if(k!=0)
        return s.Count()-k;
        else{
            return s.Distinct().Count();
        }
    }
 
    public static void Main (string[] args) {
        int[] arr = { 5, 7, 5, 5, 1, 2, 2 };
        int n = arr.Length;
        int k = 3;
 
        Console.WriteLine("Maximum distinct elements = " + maxDistinctNum(arr, n, k));
    }
}


Javascript




<script>
 
// Javascript implementation of the above approach
   
// function to find maximum distinct elements
// after removing k elements
function maxDistinctNum(a, n, k)
{
  var i;
  var s = [];
  // making multiset from given array
        for(i=0;i<n;i++){
            if(!s.includes(a[i])||k==0)
            s.push(a[i]);
            else
            {
                k--;
            }
        }
   
        if(k!=0)
            return s.size-k;
        else{
            var st = new Set();
            s.forEach(element => {
                st.add(element);
            });
             
            return st.size;
        }
}
 
// Driver Code
var arr = [5, 7, 5, 5, 1, 2, 2];
var n = arr.length;
var k = 3;
 
// Function Call
document.write( "Maximum distinct elements = "
      +  maxDistinctNum(arr, n, k));
 
// This code is contributed by itsok.
</script>


Output

Maximum distinct elements = 4

Time Complexity: O(k*logd), where d is the number of distinct elements in the given array.
Auxiliary Space: O(N), because we are using multiset.

Another Approach: Follow the below steps, to solve this problem:

  • Find the Number of distinct Toys.
  • Sum of number of element except one element form every distinct Toys.
  • Check sum if greater than or equal K then Return all distinct element.
  • Otherwise decrement number of distinct element and to fill K.
  • Return Size of vector.

Below is the implementation of the above approach:

C++




// C++ code for the above approach
#include <bits/stdc++.h>
using namespace std;
// function to return maximum number of distinct Toys
int MaxNumber(int arr[], int N, int K)
{
    // Count Number of distinct Number
    unordered_map<int, int> mp;
    for (int i = 0; i < N; i++) {
        mp[arr[i]]++;
    }
    // push them into vector
    vector<int> v1;
    for (auto i : mp) {
        v1.push_back(i.second);
    }
    // add number of element except one element from every
    // distinct element
    int temp = 0;
    for (int i = 0; i < v1.size(); i++) {
        temp += v1[i] - 1;
    }
    // check if it is greater than simply return size of
    // vector otherwise decrement size of vector to fill k
    if (K <= temp) {
        return v1.size();
    }
    else {
        K = K - temp;
        int ans = v1.size();
        while (K) {
            ans--;
            K--;
        }
        return ans;
    }
}
// Driver Code
int main()
{
    // array
    int arr[] = { 10, 10, 10, 50, 50 };
    int K = 3;
    // size of array
    int N = sizeof(arr) / sizeof(arr[0]);
    cout << MaxNumber(arr, N, K) << endl;
    return 0;
}


Java




// Java code for the above approach
import java.io.*;
import java.util.*;
 
class GFG {
 
  // Function to return maximum number of distinct Toys
  static int MaxNumber(int[] arr, int N, int K)
  {
 
    // Count Number of distinct Number
    HashMap<Integer, Integer> mp = new HashMap<>();
    for (int i = 0; i < N; i++) {
      mp.put(arr[i], mp.getOrDefault(arr[i], 0) + 1);
    }
 
    // pust them into arraylist
    List<Integer> v1 = new ArrayList<>();
    for (Map.Entry<Integer, Integer> i :
         mp.entrySet()) {
      v1.add(i.getValue());
    }
 
    // add number of element except one element from
    // every distinct element
    int temp = 0;
    for (int i = 0; i < v1.size(); i++) {
      temp += v1.get(i) - 1;
    }
 
    // check if it is greater than simply return size of
    // vector otherwise decrement size of vector to fill
    // k
    if (K <= temp) {
      return v1.size();
    }
    else {
      K = K - temp;
      int ans = v1.size();
      while (K != 0) {
        ans--;
        K--;
      }
      return ans;
    }
  }
 
  public static void main(String[] args)
  {
    int arr[] = { 10, 10, 10, 50, 50 };
    int K = 3;
    int N = arr.length;
 
    System.out.println(MaxNumber(arr, N, K));
  }
}
 
// This code is contributed by lokeshmvs21.


Python3




# Python3 code for the above approach
 
# function to return maximum number of distinct Toys
def MaxNumber(arr, N, K):
   
    # Count Number of distinct Number
    mp = {}
    for i in range(N):
        if arr[i] not in mp:
            mp[arr[i]] = 0
        mp[arr[i]] += 1
         
        # push them into vector
    v1 = []
    for i in mp:
        v1.append(mp[i])
 
     # add number of element except one element from every
    # distinct element
    temp = 0
    for i in range(len(v1)):
        temp += v1[i]-1
         
     # check if it is greater than simply return size of
    # vector otherwise decrement size of vector to fill k
    if K <= temp:
        return len(v1)
    else:
        K = K-temp
        ans = len(v1)
        while K:
            ans -= 1
            K -= 1
        return ans
 
# Driver Code
if __name__ == "__main__":
   
  # Array
    arr = [10, 10, 10, 50, 50]
    K = 3
     
    # Size of array
    N = len(arr)
    print(MaxNumber(arr, N, K))
 
    # This code is contributed by vivekmaddheshiya205


C#




// C# code for the above approach
 
using System;
using System.Collections;
using System.Collections.Generic;
 
public class GFG {
 
    // Function to return maximum number of distinct Toys
    static int MaxNumber(int[] arr, int N, int K)
    {
        // Count Number of distinct Number
        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.Add(arr[i], 1);
            }
        }
 
        // put them into arraylist
        ArrayList v1 = new ArrayList();
        foreach(KeyValuePair<int, int> i in mp)
        {
            v1.Add(i.Value);
        }
 
        // add number of element except one element from
        // every distinct element
        int temp = 0;
        for (int i = 0; i < v1.Count; i++) {
            temp += (int)v1[i] - 1;
        }
 
        // check if it is greater than simply return size of
        // vector otherwise decrement size of vector to fill
        // k
        if (K <= temp) {
            return v1.Count;
        }
        else {
            K = K - temp;
            int ans = v1.Count;
            while (K != 0) {
                ans--;
                K--;
            }
            return ans;
        }
    }
 
    static public void Main()
    {
 
        // Code
        int[] arr = { 10, 10, 10, 50, 50 };
        int K = 3;
        int N = arr.Length;
 
        Console.WriteLine(MaxNumber(arr, N, K));
    }
}
 
// This code is contributed by lokesh


Javascript




<script>
function MaxNumber(arr, N, K) {
  // Count Number of distinct Number
  let mp = new Map();
  for (let i = 0; i < N; i++) {
    if (mp.has(arr[i])) {
      mp.set(arr[i], mp.get(arr[i]) + 1);
    } else {
      mp.set(arr[i], 1);
    }
  }
  // push them into array
  let v1 = [];
  for (let i of mp) {
    v1.push(i[1]);
  }
  // add number of element except one element from every
  // distinct element
  let temp = 0;
  for (let i = 0; i < v1.length; i++) {
    temp += v1[i] - 1;
  }
  // check if it is greater than simply return size of
  // array otherwise decrement size of array to fill k
  if (K <= temp) {
    return v1.length;
  } else {
    K = K - temp;
    let ans = v1.length;
    while (K) {
      ans--;
      K--;
    }
    return ans;
  }
}
 
// Test
let arr = [10, 10, 10, 50, 50];
let K = 3;
// size of array
let N = arr.length;
console.log(MaxNumber(arr, N, K));
 
</script>


Output

2

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



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads