Minimum distinct after removing m items

Last Updated : 4 Jul, 2026

Given an array  arr[ ] of item IDs, where each element represents the ID of an item, and an integer m, remove exactly m elements from the arr[ ] such that the number of distinct item IDs remaining is minimized.

Determine and print the minimum possible number of distinct item IDs left after removing elements.

Examples: 

Input: arr[] = [2, 2, 1, 3, 3, 3], m = 3
Output: 1
Explanation: Removing {2, 2, 1} leaves {3, 3, 3}, which contains only one distinct ID..

Input: arr[] = [2, 4, 1, 5, 3, 5, 1, 3], m = 2
Output: 3
Explanation: Removing {2, 4} leaves {1, 5, 3, 5, 1, 3}, which contains three distinct IDs.

Try It Yourself
redirect icon

[Naive Approach] Using Linear Search - O(n + k ^ 2) Time O(k) Space

The idea is to first count the frequency of each element, then greedily remove elements with the smallest frequencies so that each removal eliminates a distinct element using the minimum number of deletions. We keep removing the least frequent elements until we either exhaust m or can no longer fully remove any element, and the remaining count of elements gives the minimum number of distinct elements.

C++
#include <bits/stdc++.h>
using namespace std;

// Function to minimize distinct elements
int distinctIds(vector<int> &arr, int m)
{
    unordered_map<int, int> mp;

    // Store frequency of elements
    for (int x : arr)
    {
        mp[x]++;
    }

    vector<int> freq;

    // Store frequencies
    for (auto it : mp)
    {
        freq.push_back(it.second);
    }

    int k = freq.size();

    // Repeatedly remove minimum frequency
    while (m > 0)
    {

        int mn = INT_MAX;
        int idx = -1;

        // Linear search for minimum frequency
        for (int i = 0; i < k; i++)
        {

            if (freq[i] > 0 && freq[i] < mn)
            {
                mn = freq[i];
                idx = i;
            }
        }

        // Remove current minimum frequency
        if (idx != -1 && mn <= m)
        {
            m -= mn;
            freq[idx] = 0;
        }

        else
        {
            break;
        }
    }

    int res = 0;

    // Count remaining distinct elements
    for (int x : freq)
    {

        if (x > 0)
        {
            res++;
        }
    }

    return res;
}

// Driver code
int main()
{
    vector<int> arr = {2, 4, 1, 5, 3, 5, 1, 3};

    int m = 2;

    int res = distinctIds(arr, m);

    cout << res;

    return 0;
}
Java
import java.util.HashMap;
import java.util.Map;

public class GfG {
    // Function to minimize distinct elements
    public static int distinctIds(int[] arr, int m)
    {
        Map<Integer, Integer> mp = new HashMap<>();

        // Store frequency of elements
        for (int x : arr) {
            mp.put(x, mp.getOrDefault(x, 0) + 1);
        }

        int[] freq = new int[mp.size()];
        int k = 0;

        // Store frequencies
        for (int val : mp.values()) {
            freq[k++] = val;
        }

        // Repeatedly remove minimum frequency
        while (m > 0) {
            int mn = Integer.MAX_VALUE;
            int idx = -1;

            // Linear search for minimum frequency
            for (int i = 0; i < k; i++) {
                if (freq[i] > 0 && freq[i] < mn) {
                    mn = freq[i];
                    idx = i;
                }
            }

            // Remove current minimum frequency
            if (idx != -1 && mn <= m) {
                m -= mn;
                freq[idx] = 0;
            }
            else {
                break;
            }
        }

        int res = 0;

        // Count remaining distinct elements
        for (int x : freq) {
            if (x > 0) {
                res++;
            }
        }

        return res;
    }

    public static void main(String[] args)
    {
        int[] arr = { 2, 4, 1, 5, 3, 5, 1, 3 };
        int m = 2;
        int res = distinctIds(arr, m);
        System.out.println(res);
    }
}
Python
from collections import defaultdict

# Function to minimize distinct elements


def distinctIds(arr, m):
    mp = defaultdict(int)

    # Store frequency of elements
    for x in arr:
        mp[x] += 1

    freq = list(mp.values())
    k = len(freq)

    # Repeatedly remove minimum frequency
    while m > 0:
        mn = float('inf')
        idx = -1

        # Linear search for minimum frequency
        for i in range(k):
            if freq[i] > 0 and freq[i] < mn:
                mn = freq[i]
                idx = i

        # Remove current minimum frequency
        if idx != -1 and mn <= m:
            m -= mn
            freq[idx] = 0
        else:
            break

    res = 0

    # Count remaining distinct elements
    for x in freq:
        if x > 0:
            res += 1

    return res


# Driver code
if __name__ == "__main__":
    arr = [2, 4, 1, 5, 3, 5, 1, 3]
    m = 2

    res = distinctIds(arr, m)
    print(res)
C#
using System;
using System.Collections.Generic;

public class GfG {
    // Function to minimize distinct elements
    public static int distinctIds(int[] arr, int m)
    {
        Dictionary<int, int> mp
            = new Dictionary<int, int>();

        // Store frequency of elements
        foreach(int x in arr)
        {
            if (mp.ContainsKey(x)) {
                mp[x]++;
            }
            else {
                mp[x] = 1;
            }
        }

        List<int> freq = new List<int>(mp.Values);
        int k = freq.Count;

        // Repeatedly remove minimum frequency
        while (m > 0) {
            int mn = int.MaxValue;
            int idx = -1;

            // Linear search for minimum frequency
            for (int i = 0; i < k; i++) {
                if (freq[i] > 0 && freq[i] < mn) {
                    mn = freq[i];
                    idx = i;
                }
            }

            // Remove current minimum frequency
            if (idx != -1 && mn <= m) {
                m -= mn;
                freq[idx] = 0;
            }
            else {
                break;
            }
        }

        int res = 0;

        // Count remaining distinct elements
        foreach(int x in freq)
        {
            if (x > 0) {
                res++;
            }
        }

        return res;
    }

    public static void Main()
    {
        int[] arr = { 2, 4, 1, 5, 3, 5, 1, 3 };
        int m = 2;
        int res = distinctIds(arr, m);
        Console.WriteLine(res);
    }
}
JavaScript
function distinctIds(arr, m)
{
    let mp = new Map();

    // Store frequency of elements
    for (let x of arr) {
        if (mp.has(x)) {
            mp.set(x, mp.get(x) + 1);
        }
        else {
            mp.set(x, 1);
        }
    }

    let freq = Array.from(mp.values());
    let k = freq.length;

    // Repeatedly remove minimum frequency
    while (m > 0) {
        let mn = Infinity;
        let idx = -1;

        // Linear search for minimum frequency
        for (let i = 0; i < k; i++) {
            if (freq[i] > 0 && freq[i] < mn) {
                mn = freq[i];
                idx = i;
            }
        }

        // Remove current minimum frequency
        if (idx !== -1 && mn <= m) {
            m -= mn;
            freq[idx] = 0;
        }
        else {
            break;
        }
    }

    let res = 0;

    // Count remaining distinct elements
    for (let x of freq) {
        if (x > 0) {
            res++;
        }
    }

    return res;
}

// Driver code
let arr = [ 2, 4, 1, 5, 3, 5, 1, 3 ];
let m = 2;
let res = distinctIds(arr, m);
console.log(res);

Output
3

[Better Approach] Using Hash Map and Sorting - O(n + k log k) Time O(k) Space

The idea is to first count the frequency of each element and store it in a list. Since removing all occurrences of a number removes one distinct element, we sort the frequencies in ascending order and greedily remove the smallest ones first. We keep subtracting frequencies from m while it is possible, reducing the number of distinct elements each time a full group is removed. The remaining count of frequencies gives the minimum number of distinct elements left.

C++
#include <bits/stdc++.h>
using namespace std;

// Function to minimize distinct elements
int distinctIds(vector<int> &arr, int m)
{
    unordered_map<int, int> mp;

    // Store frequency of elements
    for (int x : arr)
    {
        mp[x]++;
    }

    vector<int> freq;

    // Store frequencies
    for (auto it : mp)
    {
        freq.push_back(it.second);
    }

    // Sort frequencies
    sort(freq.begin(), freq.end());

    int res = freq.size();

    // Remove smaller frequencies first
    for (int x : freq)
    {

        if (x <= m)
        {
            m -= x;
            res--;
        }

        else
        {
            break;
        }
    }

    return res;
}

// Driver code
int main()
{
    vector<int> arr = {2, 4, 1, 5, 3, 5, 1, 3};

    int m = 2;

    int res = distinctIds(arr, m);

    cout << res;

    return 0;
}
Java
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

// Function to minimize distinct elements
public class GfG {
    public static int distinctIds(int[] arr, int m)
    {
        Map<Integer, Integer> mp = new HashMap<>();

        // Store frequency of elements
        for (int x : arr) {
            mp.put(x, mp.getOrDefault(x, 0) + 1);
        }

        int[] freq = new int[mp.size()];
        int index = 0;

        // Store frequencies
        for (int val : mp.values()) {
            freq[index++] = val;
        }

        // Sort frequencies
        Arrays.sort(freq);

        int res = freq.length;

        // Remove smaller frequencies first
        for (int x : freq) {

            if (x <= m) {
                m -= x;
                res--;
            }

            else {
                break;
            }
        }

        return res;
    }

    // Driver code
    public static void main(String[] args)
    {
        int[] arr = { 2, 4, 1, 5, 3, 5, 1, 3 };

        int m = 2;

        int res = distinctIds(arr, m);

        System.out.println(res);
    }
}
Python
from collections import Counter
import operator

# Function to minimize distinct elements


def distinctIds(arr, m):
    mp = Counter(arr)

    # Store frequencies
    freq = list(mp.values())

    # Sort frequencies
    freq.sort()

    res = len(freq)

    # Remove smaller frequencies first
    for x in freq:
        if x <= m:
            m -= x
            res -= 1
        else:
            break

    return res


# Driver code
if __name__ == "__main__":
    arr = [2, 4, 1, 5, 3, 5, 1, 3]
    m = 2

    res = distinctIds(arr, m)
    print(res)
C#
using System;
using System.Collections.Generic;
using System.Linq;

// Function to minimize distinct elements
public class GfG {
    public static int distinctIds(int[] arr, int m)
    {
        Dictionary<int, int> mp
            = new Dictionary<int, int>();

        // Store frequency of elements
        foreach(int x in arr)
        {
            if (mp.ContainsKey(x)) {
                mp[x]++;
            }
            else {
                mp[x] = 1;
            }
        }

        int[] freq = new int[mp.Count];
        int index = 0;

        // Store frequencies
        foreach(int val in mp.Values)
        {
            freq[index++] = val;
        }

        // Sort frequencies
        Array.Sort(freq);

        int res = freq.Length;

        // Remove smaller frequencies first
        foreach(int x in freq)
        {

            if (x <= m) {
                m -= x;
                res--;
            }

            else {
                break;
            }
        }

        return res;
    }

    // Driver code
    public static void Main()
    {
        int[] arr = { 2, 4, 1, 5, 3, 5, 1, 3 };

        int m = 2;

        int res = distinctIds(arr, m);

        Console.WriteLine(res);
    }
}
JavaScript
// Function to minimize distinct elements
function distinctIds(arr, m) {
    let mp = new Map();

    // Store frequency of elements
    for (let x of arr) {
        if (mp.has(x)) {
            mp.set(x, mp.get(x) + 1);
        } else {
            mp.set(x, 1);
        }
    }

    let freq = [];

    // Store frequencies
    for (let val of mp.values()) {
        freq.push(val);
    }

    // Sort frequencies
    freq.sort((a, b) => a - b);

    let res = freq.length;

    // Remove smaller frequencies first
    for (let x of freq) {
        if (x <= m) {
            m -= x;
            res--;
        } else {
            break;
        }
    }

    return res;
}

// Driver code
let arr = [2, 4, 1, 5, 3, 5, 1, 3];
let m = 2;
let res = distinctIds(arr, m);
console.log(res);

Output
3

[Expected Approach] Using Greedy and Frequency Counting - O(n) Time O(n) Space

The idea is to minimize distinct elements by removing m items optimally. First, we count the frequency of each element. Since removing all occurrences of an element removes one distinct value, we greedily target elements with the smallest frequencies first because they cost the least deletions to eliminate. We sort (or bucket) frequencies and keep removing the smallest ones while m allows. Each full removal of a frequency reduces the distinct count by one. The remaining number of frequencies represents the minimum distinct elements left.

Let us understand with example:
Input: arr[] = [2, 4, 1, 5, 3, 5, 1, 3], m = 2

  • Frequencies stored in map: [2:1, 4:1, 1:2, 5:2, 3:2]
  • Bucket array stores count of frequencies: bucket[1] = 2, bucket[2] = 3
  • Initially distinct elements res = 5
  • For frequency 1, remove element 2 completely -> m = 1, res = 4; 
  • remove element 4 completely -> m = 0, res = 3
  • Since m = 0, stop processing. Remaining distinct elements are [1, 3, 5].

So, Output is 3

C++
#include <bits/stdc++.h>
using namespace std;

// Function to find minimum number of distinct elements
// after removing exactly m elements
int distinctIds(vector<int> &arr, int m)
{
    unordered_map<int, int> mp;

    // Store frequency of each element
    for (int x : arr)
        mp[x]++;

    int n = arr.size();

    // Create a bucket where index represents frequency
    // bucket[i] = number of elements having frequency i
    vector<int> bucket(n + 1, 0);

    for (auto it : mp)
    {
        bucket[it.second]++;
    }

    // Initially all distinct elements are present
    int res = mp.size();

    // Greedily remove elements with smallest frequency first
    // because they reduce distinct count with minimum removals
    for (int i = 1; i <= n && m > 0; i++)
    {
        // While we still have elements with frequency i
        // and enough m to remove them completely
        while (bucket[i] > 0 && m >= i)
        {
            // remove all occurrences of one element
            m -= i;

            // one element removed from this frequency group
            bucket[i]--;

            // decrease distinct count
            res--;
        }
    }

    // Return remaining distinct elements
    return res;
}

// Driver code
int main()
{
    vector<int> arr = {2, 4, 1, 5, 3, 5, 1, 3};
    int m = 2;

    cout << distinctIds(arr, m);

    return 0;
}
Java
import java.util.*;

class GfG {

    // Function to find minimum number of distinct elements
    // after removing exactly m elements
    static int distinctIds(int[] arr, int m)
    {

        HashMap<Integer, Integer> mp = new HashMap<>();

        // Store frequency of each element
        for (int x : arr) {
            mp.put(x, mp.getOrDefault(x, 0) + 1);
        }

        int n = arr.length;

        // Create a bucket where index represents frequency
        // bucket[i] = number of elements having frequency i
        int[] bucket = new int[n + 1];

        for (int freq : mp.values()) {
            bucket[freq]++;
        }

        // Initially all distinct elements are present
        int res = mp.size();

        // Greedily remove elements with smallest frequency
        // first because they reduce distinct count with
        // minimum removals
        for (int i = 1; i <= n && m > 0; i++) {

            // While we still have elements with frequency i
            // and enough m to remove them completely
            while (bucket[i] > 0 && m >= i) {

                // remove all occurrences of one element
                m -= i;

                // one element removed from this frequency
                // group
                bucket[i]--;

                // decrease distinct count
                res--;
            }
        }

        // Return remaining distinct elements
        return res;
    }

    // Driver code
    public static void main(String[] args)
    {

        int[] arr = { 2, 4, 1, 5, 3, 5, 1, 3 };
        int m = 2;

        System.out.println(distinctIds(arr, m));
    }
}
Python
from collections import defaultdict

# Function to find minimum number of distinct elements
# after removing exactly m elements


def distinctIds(arr, m):
    mp = defaultdict(int)

    # Store frequency of each element
    for x in arr:
        mp[x] += 1

    n = len(arr)

    # Create a bucket where index represents frequency
    # bucket[i] = number of elements having frequency i
    bucket = [0] * (n + 1)

    for freq in mp.values():
        bucket[freq] += 1

    # Initially all distinct elements are present
    res = len(mp)

    # Greedily remove elements with smallest frequency first
    # because they reduce distinct count with minimum removals
    for i in range(1, n + 1):
        while bucket[i] > 0 and m >= i:
            # remove all occurrences of one element
            m -= i

            # one element removed from this frequency group
            bucket[i] -= 1

            # decrease distinct count
            res -= 1

    # Return remaining distinct elements
    return res


# Driver code
if __name__ == "__main__":
    arr = [2, 4, 1, 5, 3, 5, 1, 3]
    m = 2

    res = distinctIds(arr, m)
    print(res)
C#
using System;
using System.Collections.Generic;

class GfG {

    // Function to find minimum number of distinct elements
    // after removing exactly m elements
    static int distinctIds(int[] arr, int m)
    {

        Dictionary<int, int> mp
            = new Dictionary<int, int>();

        // Store frequency of each element
        foreach(int x in arr)
        {
            if (mp.ContainsKey(x))
                mp[x]++;
            else
                mp[x] = 1;
        }

        int n = arr.Length;

        // Create a bucket where index represents frequency
        // bucket[i] = number of elements having frequency i
        int[] bucket = new int[n + 1];

        foreach(var it in mp) { bucket[it.Value]++; }

        // Initially all distinct elements are present
        int res = mp.Count;

        // Greedily remove elements with smallest frequency
        // first because they reduce distinct count with
        // minimum removals
        for (int i = 1; i <= n && m > 0; i++) {

            // While we still have elements with frequency i
            // and enough m to remove them completely
            while (bucket[i] > 0 && m >= i) {

                // remove all occurrences of one element
                m -= i;

                // one element removed from this frequency
                // group
                bucket[i]--;

                // decrease distinct count
                res--;
            }
        }

        // Return remaining distinct elements
        return res;
    }

    // Driver code
    static void Main()
    {

        int[] arr = { 2, 4, 1, 5, 3, 5, 1, 3 };
        int m = 2;

        Console.WriteLine(distinctIds(arr, m));
    }
}
JavaScript
// Function to find minimum number of distinct elements
// after removing exactly m elements
function distinctIds(arr, m)
{
    const mp = new Map();

    // Store frequency of each element
    for (const x of arr) {
        if (mp.has(x)) {
            mp.set(x, mp.get(x) + 1);
        }
        else {
            mp.set(x, 1);
        }
    }

    const n = arr.length;

    // Create a bucket where index represents frequency
    // bucket[i] = number of elements having frequency i
    const bucket = new Array(n + 1).fill(0);

    for (const freq of mp.values()) {
        bucket[freq]++;
    }

    // Initially all distinct elements are present
    let res = mp.size;

    // Greedily remove elements with smallest frequency
    // first because they reduce distinct count with minimum
    // removals
    for (let i = 1; i <= n && m > 0; i++) {
        while (bucket[i] > 0 && m >= i) {
            // remove all occurrences of one element
            m -= i;

            // one element removed from this frequency group
            bucket[i]--;

            // decrease distinct count
            res--;
        }
    }

    // Return remaining distinct elements
    return res;
}

// Driver code
const arr = [ 2, 4, 1, 5, 3, 5, 1, 3 ];
const m = 2;

console.log(distinctIds(arr, m));

Output
3
Comment