Open In App

Maximum possible size of subset following the given constraints

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

Given an array arr[] of size n, the task is to find the maximum possible size x of a subset such that there are exactly two subsets of the same size that should follow the below constraints:

  • The first subset should consist of distinct elements (i.e., all elements in the first subset are unique) and it might have one element in common with the second subset.
  • The second subset should consist of all same elements (i.e., all elements in the second subset are equal)

Examples: 

Input: arr[] = {4, 2, 4, 1, 4, 3, 4}
Output: 3
Explanation: It is possible to construct two subsets of size 3: the first subset is [1, 2, 4] and the second subset is [4, 4, 4]. Note, that there are some other ways to construct two valid teams of size 3.

Input: arr[] = {1, 1, 1, 3}
Output: 2
Explanation: It is possible to construct two subsets of size 2: the first subset is [1, 3] and the second subset is [1, 1].

Approach: Implement the idea below to solve the problem:

  • Let’s suppose we are able to make two subsets using the given constraints with size x, So, in order to find the maximum size possible, we store the current size x in our answer variable and update low with mid + 1
  • If we were not able to create two subsets using the given constraints with size x, it is sure we would not be able to create two subsets from size x + 1 to n, so we would update high as mid – 1.
  • We can get to know if it is possible to form two subsets using the given constraints is possible or not using the map, we can store the frequency of each element in the map and if the frequency of any element is greater than or equal to the size we are checking on and as well as the size of the map-1 should be greater than or equal to the size we are checking on, we would subtract the map size by -1 because it stores the count of distinct elements and 1 element is already used to create the subset which contains all same elements.

Follow the steps mentioned below to implement the idea:

  • Initialize low as 0 and high as n/2 initially.
  • Calculate mid and check if is it possible to create two subsets using the given constraints
  • If possible, update ans to mid (current size) and low to mid +1.
  • Else, update high to mid – 1.
  • Use a map to store the frequency of each element and to know the possibility of subset formation.
  • If the size of the map – 1 is greater than or equal to the size we are checking on and any element is appearing more than or equal to the size we are checking on, then it is always possible to form two subsets so return true else false.

Below is the implementation of the above approach:

C++




// C++ code to implement the approach
#include <bits/stdc++.h>
using namespace std;
 
// Function for checking if is it possible
// to create two subsets using the given
// constraints with the size mid
bool is_possible(unordered_map<int, int>& mpp, int mid)
{
    bool flag1 = false;
    bool flag2 = false;
    bool flag = false;
    for (auto it : mpp) {
        if (it.second >= mid) {
            flag1 = true;
            if (it.second > mid)
                flag2 = true;
        }
    }
 
    int size = mpp.size() - 1;
    if (flag2)
        size += 1;
 
    return flag1 && size >= mid;
}
 
// Function for finding out the
// maximum size
int maximum_size(vector<int>& arr, int n)
{
 
    // Declare map for storing
    // the frequency of each element
    unordered_map<int, int> mpp;
    for (auto it : arr) {
        mpp[it]++;
    }
 
    // Range of binary search
    int low = 0;
    int high = n / 2;
 
    // Store the maximum size
    int ans = 0;
 
    while (low <= high) {
 
        // Calculating mid
        int mid = (low + high) >> 1;
 
        // If it possible to create two
        // subsets, store mid in ans and
        // update low as mid+1 in order to
        // find the maximum possible size
        if (is_possible(mpp, mid)) {
 
            ans = mid;
            low = mid + 1;
        }
 
        // If it is not possible to create
        // two subsets, it would not be
        // possible to create subsets from
        // size mid to n thus, update high
        // as mid -1
        else {
            high = mid - 1;
        }
    }
 
    // Return the maximum possible size
    return ans;
}
 
// Driver code
int main()
{
    vector<int> arr = { 4, 2, 4, 1, 4, 3, 4 };
    int n = arr.size();
 
    // Function call
    cout << maximum_size(arr, n);
    return 0;
}


Java




// Java code to implement the approach
import java.util.*;
public class Main {
 
  // Function for checking if is it possible
  // to create two subsets using the given
  // constraints with the size mid
  static boolean is_possible(Map<Integer, Integer> mpp, int mid)
  {
    boolean flag1 = false;
    boolean flag2 = false;
    boolean flag = false;
    for (Map.Entry it : mpp.entrySet()) {
      if ((int)it.getValue() >= mid) {
        flag1 = true;
        if ((int)it.getValue() > mid)
          flag2 = true;
      }
    }
 
    int size = mpp.size() - 1;
    if (flag2)
      size += 1;
 
    return flag1 && size >= mid;
  }
 
  // Function for finding out the
  // maximum size
  static int maximum_size(int[] arr, int n)
  {
 
    // Declare map for storing
    // the frequency of each element
    Map<Integer, Integer> mpp = new HashMap<Integer, Integer>();
    for (int it : arr) {
      if(mpp.containsKey(it)){
        mpp.put(it, mpp.get(it)+1);
      }
      else{
        mpp.put(it,1);
      }
    }
 
    // Range of binary search
    int low = 0;
    int high = n / 2;
 
    // Store the maximum size
    int ans = 0;
 
    while (low <= high) {
 
      // Calculating mid
      int mid = (low + high) >> 1;
 
      // If it possible to create two
      // subsets, store mid in ans and
      // update low as mid+1 in order to
      // find the maximum possible size
      if (is_possible(mpp, mid)) {
 
        ans = mid;
        low = mid + 1;
      }
 
      // If it is not possible to create
      // two subsets, it would not be
      // possible to create subsets from
      // size mid to n thus, update high
      // as mid -1
      else {
        high = mid - 1;
      }
    }
 
    // Return the maximum possible size
    return ans;
  }
 
  // Driver code
  public static void main(String[] args)
  {
    int[] arr = { 4, 2, 4, 1, 4, 3, 4 };
    int n = arr.length;
 
    // Function call
    System.out.println(maximum_size(arr, n));
  }
}
 
// This code is contributed by ishankhandelwals.


C#




// C# code to implement the approach
 
using System;
using System.Collections.Generic;
 
public class GFG {
 
    // Function for checking if is it possible to create two
    // subsets using the given constraints with the size mid
    static bool is_possible(Dictionary<int, int> mpp,
                            int mid)
    {
        bool flag1 = false;
        bool flag2 = false;
        foreach(KeyValuePair<int, int> it in mpp)
        {
            if (it.Value >= mid) {
                flag1 = true;
                if (it.Value > mid)
                    flag2 = true;
            }
        }
 
        int size = mpp.Count - 1;
        if (flag2)
            size += 1;
 
        return flag1 && size >= mid;
    }
 
    // Function for finding out the maximum size
    static int maximum_size(int[] arr, int n)
    {
 
        // Declare map for storing the frequency of each
        // element
        Dictionary<int, int> mpp
            = new Dictionary<int, int>();
        foreach(int it in arr)
        {
            if (mpp.ContainsKey(it)) {
                mpp[it] = mpp[it] + 1;
            }
            else {
                mpp.Add(it, 1);
            }
        }
 
        // Range of binary search
        int low = 0;
        int high = n / 2;
 
        // Store the maximum size
        int ans = 0;
 
        while (low <= high) {
 
            // Calculating mid
            int mid = (low + high) / 2;
 
            // If it possible to create two subsets, store
            // mid in ans and update low as mid+1 in order
            // to find the maximum possible size
            if (is_possible(mpp, mid)) {
 
                ans = mid;
                low = mid + 1;
            }
 
            // If it is not possible to create two subsets,
            // it would not be possible to create subsets
            // from size mid to n thus, update high as mid
            // -1
            else {
                high = mid - 1;
            }
        }
 
        // Return the maximum possible size
        return ans;
    }
 
    static public void Main()
    {
 
        // Code
        int[] arr = { 4, 2, 4, 1, 4, 3, 4 };
        int n = arr.Length;
 
        // Function call
        Console.WriteLine(maximum_size(arr, n));
    }
}
 
// This code is contributed by lokeshmvs21.


Python3




# Python implementation of the approach
from collections import defaultdict
 
# Function for checking if it is possible
# to create two subsets using the given
# constraints with the size mid
def is_possible(mpp, mid):
    flag1 = False
    flag2 = False
    for key, value in mpp.items():
        if value >= mid:
            flag1 = True
            if value > mid:
                flag2 = True
    size = len(mpp) - 1
    if flag2:
        size += 1
    return flag1 and size >= mid
 
# Function for finding out the
# maximum size
def maximum_size(arr):
    # Dictionary for storing
    # the frequency of each element
    mpp = defaultdict(int)
    for i in arr:
        mpp[i] += 1
 
    # Range of binary search
    low = 0
    high = len(arr) // 2
 
    # Store the maximum size
    ans = 0
 
    while low <= high:
        # Calculating mid
        mid = (low + high) // 2
 
        # If it is possible to create two
        # subsets, store mid in ans and
        # update low as mid + 1 in order to
        # find the maximum possible size
        if is_possible(mpp, mid):
            ans = mid
            low = mid + 1
        # If it is not possible to create
        # two subsets, it would not be
        # possible to create subsets from
        # size mid to n, thus update high
        # as mid -1
        else:
            high = mid - 1
    # Return the maximum possible size
    return ans
 
# Driver code
arr = [4, 2, 4, 1, 4, 3, 4]
 
# Function call
print(maximum_size(arr))
 
#code by ksam24000


Javascript




// Function for checking if it is possible
// to create two subsets using the given
// constraints with the size mid
function is_possible(mpp, mid) {
  let flag1 = false;
  let flag2 = false;
  let flag = false;
 
  // Iterate through the unordered_map
  for (let [key, value] of Object.entries(mpp)) {
    if (value >= mid) {
      flag1 = true;
      if (value > mid) {
        flag2 = true;
      }
    }
  }
 
  let size = Object.keys(mpp).length - 1;
  if (flag2) {
    size += 1;
  }
 
  return flag1 && size >= mid;
}
 
// Function for finding out the
// maximum size
function maximum_size(arr, n) {
  // Declare map for storing
  // the frequency of each element
  let mpp = {};
 
  // Count the frequency of each element in arr
  for (let i = 0; i < n; i++) {
    mpp[arr[i]] = mpp[arr[i]] ? mpp[arr[i]] + 1 : 1;
  }
 
  // Range of binary search
  let low = 0;
  let high = Math.floor(n / 2);
 
  // Store the maximum size
  let ans = 0;
 
  while (low <= high) {
    // Calculating mid
    let mid = Math.floor((low + high) / 2);
 
    // If it possible to create two
    // subsets, store mid in ans and
    // update low as mid+1 in order to
    // find the maximum possible size
    if (is_possible(mpp, mid)) {
      ans = mid;
      low = mid + 1;
    }
    // If it is not possible to create
    // two subsets, it would not be
    // possible to create subsets from
    // size mid to n thus, update high
    // as mid -1
    else {
      high = mid - 1;
    }
  }
 
  // Return the maximum possible size
  return ans;
}
 
// Driver code
let arr = [4, 2, 4, 1, 4, 3, 4];
let n = arr.length;
 
// Function call
console.log(maximum_size(arr, n));


Output

3

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

Related Articles:



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

Similar Reads