 Open in App
Not now

# Maximum possible size of subset following the given constraints

• Difficulty Level : Hard
• Last Updated : 22 Feb, 2023

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 ` `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 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 mpp = ``new` `HashMap();` `    ``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:

My Personal Notes arrow_drop_up
Related Articles