Minimum Subsets with Distinct Elements

Last Updated : 7 Apr, 2026

You are given an array of n-element. You have to make subsets from the array such that no subset contain duplicates. Find out minimum number of subset possible.

Examples : 

Input : arr[] = {1, 2, 3, 4}
Output :1
Explanation : A single subset can contains all values and all values are distinct.

Input : arr[] = {1, 2, 3, 3}
Output : 2
Explanation : We need to create two subsets {1, 2, 3} and {3} [or {1, 3} and {2, 3}] such that both subsets have distinct elements.

[Naive Solution] - Nested Loops - O(n^2) Time and O(1) Space

Let us take a look at few observations.

  • If all elements are distinct, we need to make only one subset.
  • If all elements are same, we need make n subsets.
  • If only one element appears twice, and all other are distinct, we need to make two subsets. For example for {1, 2, 3, 2, 4}, the two subsets are {1} and {1, 2, 3, 4}

Did you see any pattern?
We basically need to find the most frequent element in the array. The result is equal to the frequency of the most frequent element. Since we have to create a subset such that each element in a subset is unique that means that all the repeating elements should be kept in a different set. Hence the maximum number of subsets that we require is the frequency of the maximum time occurring element.

Ex -> { 1 , 2 , 1 , 2 , 3 , 3 , 2 , 2 }
here
Frequency of 1 -> 2
Frequency of 2 -> 4
Frequency of 3 -> 2

Since the frequency of 2 is maximum hence we need to have at least 4 subset to keep all the 2 in different subsets and rest of element can be occupied accordingly.

The naive approach involves using two nested loops: the outer loop picks each element, and the inner loop counts the frequency of the picked element. This method is straightforward but inefficient.

C++
#include <iostream>
using namespace std;

int minSubsets(vector<int> &arr)
{
    int n = arr.size(), maxCount = 0;
    int res;
    for (int i = 0; i < n; i++) {
        int count = 0;
        for (int j = 0; j < n; j++) {
            if (arr[i] == arr[j])
                count++;
        }

        if (count > maxCount) {
            maxCount = count;
            res = arr[i];
        }
    }

    return maxCount;
}

int main()
{
    vector<int> arr = { 40, 50, 30, 40, 50, 30, 30 };
    cout << minSubsets(arr);
    return 0;
}
Java
class GfG {
    static int minSubsets(int[] arr) {
        int n = arr.length, maxCount = 0, res = arr[0];

        for (int i = 0; i < n; i++) {
            int count = 0;
            for (int j = 0; j < n; j++) {
                if (arr[i] == arr[j]) count++;
            }

            if (count > maxCount) {
                maxCount = count;
                res = arr[i];
            }
        }
        return maxCount;
    }

    public static void main(String[] args) {
        int[] arr = {40, 50, 30, 40, 50, 30, 30};
        System.out.println(minSubsets(arr));
    }
}
Python
def minSubsets(arr):
    n, maxCount, res = len(arr), 0, arr[0]

    for i in range(n):
        count = sum(1 for j in range(n) if arr[i] == arr[j])

        if count > maxCount:
            maxCount = count
            res = arr[i]

    return maxCount

arr = [40, 50, 30, 40, 50, 30, 30]
print(minSubsets(arr))
C#
using System;
using System.Collections.Generic;

class GFG
{
    static int minSubsets(List<int> arr)
    {
        int n = arr.Count, maxCount = 0;
        int res = 0;

        for (int i = 0; i < n; i++){
            int count = 0;
            for (int j = 0; j < n; j++){
                if (arr[i] == arr[j])
                    count++;
            }

            if (count > maxCount){
                maxCount = count;
                res = arr[i];
            }
        }

        return maxCount;
    }

    static void Main()
    {
        List<int> arr = new List<int> { 40, 50, 30, 40, 50, 30, 30 };
        Console.WriteLine(minSubsets(arr));
    }
}
JavaScript
function minSubsets(arr) {
    let n = arr.length, maxCount = 0, res = arr[0];

    for (let i = 0; i < n; i++) {
        let count = 0;
        for (let j = 0; j < n; j++) {
            if (arr[i] === arr[j]) count++;
        }

        if (count > maxCount) {
            maxCount = count;
            res = arr[i];
        }
    }
    return maxCount;
}

// Driver Code
let arr = [40, 50, 30, 40, 50, 30, 30];
console.log(minSubsets(arr));

Output
3

[Better Approach] - Using Sorting - O(n log n) Time and O(1) Space

This method sorts the array first and then finds the maximum frequency by linearly traversing the sorted array. Sorting brings similar elements next to each other, making frequency counting easier.

C++
#include <iostream>
using namespace std;

int minSubsets(vector<int>& arr)
{
    // Sort the array
    sort(arr.begin(), arr.end());

    // Find the max frequency using linear traversal
    int maxCount = 1, res = arr[0], currCount = 1;
    for (int i = 1; i < arr.size(); i++) {
        if (arr[i] == arr[i - 1])
            currCount++;
        else
            currCount = 1;
        
        if (currCount > maxCount) {
            maxCount = currCount;
            res = arr[i - 1];
        }
    }

    return maxCount;
}

int main()
{
    vector<int> arr = {40, 50, 30, 40, 50, 30, 30};
    cout << minSubsets(arr);
    return 0;
}
Java
import java.util.*;

class GFG {

    static int minSubsets(int[] arr)
    {
        // Sort the array
        Arrays.sort(arr);

        // Find the max frequency using linear traversal
        int maxCount = 1, res = arr[0], currCount = 1;
        for (int i = 1; i < arr.length; i++) {
            if (arr[i] == arr[i - 1])
                currCount++;
            else
                currCount = 1;
            
            if (currCount > maxCount) {
                maxCount = currCount;
                res = arr[i - 1];
            }
        }

        return maxCount;
    }

    public static void main(String[] args)
    {
        int[] arr = {40, 50, 30, 40, 50, 30, 30};
        System.out.println(minSubsets(arr));
    }
}
Python
def minSubsets(arr):
    
    # Sort the array
    arr.sort()

    # Find the max frequency using linear traversal
    maxCount, res, currCount = 1, arr[0], 1
    for i in range(1, len(arr)):
        if arr[i] == arr[i - 1]:
            currCount += 1
        else:
            currCount = 1
        
        if currCount > maxCount:
            maxCount = currCount
            res = arr[i - 1]

    return maxCount


arr = [40, 50, 30, 40, 50, 30, 30]
print(minSubsets(arr))
C#
using System;

class GFG {

    static int minSubsets(int[] arr)
    {
        // Sort the array
        Array.Sort(arr);

        // Find the max frequency using linear traversal
        int maxCount = 1, res = arr[0], currCount = 1;
        for (int i = 1; i < arr.Length; i++) {
            if (arr[i] == arr[i - 1])
                currCount++;
            else
                currCount = 1;
            
            if (currCount > maxCount) {
                maxCount = currCount;
                res = arr[i - 1];
            }
        }

        return maxCount;
    }

    static void Main()
    {
        int[] arr = {40, 50, 30, 40, 50, 30, 30};
        Console.WriteLine(minSubsets(arr));
    }
}
JavaScript
function minSubsets(arr)
{
    // Sort the array
    arr.sort((a, b) => a - b);

    // Find the max frequency using linear traversal
    let maxCount = 1, res = arr[0], currCount = 1;
    for (let i = 1; i < arr.length; i++) {
        if (arr[i] === arr[i - 1])
            currCount++;
        else
            currCount = 1;
        
        if (currCount > maxCount) {
            maxCount = currCount;
            res = arr[i - 1];
        }
    }

    return maxCount;
}

// Driver Code
let arr = [40, 50, 30, 40, 50, 30, 30];
console.log(minSubsets(arr));

Output
3

[Expected Approach] - Using Hashing - O(n) Time and O(n) Space

Using a hash table, this approach stores each element's frequency and then finds the element with the maximum frequency.

C++
#include <iostream>
#include <vector>
#include <unordered_map>
using namespace std;

int minSubsets(vector<int>& arr)
{
    // Insert all elements in hash.
    unordered_map<int, int> freq;
    for (int i = 0; i < arr.size(); i++)
        freq[arr[i]]++;

    // find the max frequency
    int maxCount = 0, res = -1;
    for (auto i : freq) {
        if (maxCount < i.second) {
            res = i.first;
            maxCount = i.second;
        }
    }

    return maxCount;
}

int main()
{
    vector<int> arr = {40,50,30,40,50,30,30};
    cout << minSubsets(arr);
    return 0;
}
Java
import java.util.*;

class GFG {

    static int minSubsets(int[] arr)
    {
        // Insert all elements in hash.
        HashMap<Integer, Integer> freq = new HashMap<>();
        for (int i = 0; i < arr.length; i++)
            freq.put(arr[i], freq.getOrDefault(arr[i], 0) + 1);

        // find the max frequency
        int maxCount = 0, res = -1;
        for (Map.Entry<Integer, Integer> i : freq.entrySet()) {
            if (maxCount < i.getValue()) {
                res = i.getKey();
                maxCount = i.getValue();
            }
        }

        return maxCount;
    }

    public static void main(String[] args)
    {
        int[] arr = {40,50,30,40,50,30,30};
        System.out.println(minSubsets(arr));
    }
}
Python
def minSubsets(arr):
    
    # Insert all elements in hash.
    freq = {}
    for i in range(len(arr)):
        freq[arr[i]] = freq.get(arr[i], 0) + 1

    # find the max frequency
    maxCount, res = 0, -1
    for key, value in freq.items():
        if maxCount < value:
            res = key
            maxCount = value

    return maxCount

arr = [40,50,30,40,50,30,30]
n = len(arr)
print(minSubsets(arr))
C#
using System;
using System.Collections.Generic;

class GFG {

    static int minSubsets(int[] arr)
    {
        // Insert all elements in hash.
        Dictionary<int, int> freq = new Dictionary<int, int>();
        for (int i = 0; i < arr.Length; i++)
            freq[arr[i]] = freq.ContainsKey(arr[i])? freq[arr[i]] + 1 : 1;

        // find the max frequency
        int maxCount = 0, res = -1;
        foreach (var i in freq) {
            if (maxCount < i.Value) {
                res = i.Key;
                maxCount = i.Value;
            }
        }

        return maxCount;
    }

    public static void Main(string[] args)
    {
        int[] arr = {40,50,30,40,50,30,30};
        Console.WriteLine(minSubsets(arr));
    }
}
JavaScript
function minSubsets(arr) {

    // Insert all elements in hash.
    let freq = {};
    for (let i = 0; i < arr.length; i++) {
        freq[arr[i]] = (freq[arr[i]] || 0) + 1;
    }

    // find the max frequency
    let maxCount = 0, res = -1;
    for (let key in freq) {
        if (maxCount < freq[key]) {
            res = key;
            maxCount = freq[key];
        }
    }

    return maxCount;
}

let arr = [40,50,30,40,50,30,30];
let n = arr.length;
console.log(minSubsets(arr));

Output
3
Comment