Maximum possible size of subset following the given constraints
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++
#include <bits/stdc++.h>
using namespace std;
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;
}
int maximum_size(vector< int >& arr, int n)
{
unordered_map< int , int > mpp;
for ( auto it : arr) {
mpp[it]++;
}
int low = 0;
int high = n / 2;
int ans = 0;
while (low <= high) {
int mid = (low + high) >> 1;
if (is_possible(mpp, mid)) {
ans = mid;
low = mid + 1;
}
else {
high = mid - 1;
}
}
return ans;
}
int main()
{
vector< int > arr = { 4, 2, 4, 1, 4, 3, 4 };
int n = arr.size();
cout << maximum_size(arr, n);
return 0;
}
|
Java
import java.util.*;
public class Main {
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;
}
static int maximum_size( int [] arr, int n)
{
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 );
}
}
int low = 0 ;
int high = n / 2 ;
int ans = 0 ;
while (low <= high) {
int mid = (low + high) >> 1 ;
if (is_possible(mpp, mid)) {
ans = mid;
low = mid + 1 ;
}
else {
high = mid - 1 ;
}
}
return ans;
}
public static void main(String[] args)
{
int [] arr = { 4 , 2 , 4 , 1 , 4 , 3 , 4 };
int n = arr.length;
System.out.println(maximum_size(arr, n));
}
}
|
C#
using System;
using System.Collections.Generic;
public class GFG {
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;
}
static int maximum_size( int [] arr, int n)
{
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);
}
}
int low = 0;
int high = n / 2;
int ans = 0;
while (low <= high) {
int mid = (low + high) / 2;
if (is_possible(mpp, mid)) {
ans = mid;
low = mid + 1;
}
else {
high = mid - 1;
}
}
return ans;
}
static public void Main()
{
int [] arr = { 4, 2, 4, 1, 4, 3, 4 };
int n = arr.Length;
Console.WriteLine(maximum_size(arr, n));
}
}
|
Python3
from collections import defaultdict
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
def maximum_size(arr):
mpp = defaultdict( int )
for i in arr:
mpp[i] + = 1
low = 0
high = len (arr) / / 2
ans = 0
while low < = high:
mid = (low + high) / / 2
if is_possible(mpp, mid):
ans = mid
low = mid + 1
else :
high = mid - 1
return ans
arr = [ 4 , 2 , 4 , 1 , 4 , 3 , 4 ]
print (maximum_size(arr))
|
Javascript
function is_possible(mpp, mid) {
let flag1 = false ;
let flag2 = false ;
let flag = false ;
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 maximum_size(arr, n) {
let mpp = {};
for (let i = 0; i < n; i++) {
mpp[arr[i]] = mpp[arr[i]] ? mpp[arr[i]] + 1 : 1;
}
let low = 0;
let high = Math.floor(n / 2);
let ans = 0;
while (low <= high) {
let mid = Math.floor((low + high) / 2);
if (is_possible(mpp, mid)) {
ans = mid;
low = mid + 1;
}
else {
high = mid - 1;
}
}
return ans;
}
let arr = [4, 2, 4, 1, 4, 3, 4];
let n = arr.length;
console.log(maximum_size(arr, n));
|
Time Complexity: O(N*logN)
Auxiliary Space: O(N)
Related Articles:
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...