Maximize numbers that can be grouped together based on given conditions
Last Updated :
21 Jul, 2022
Given a 2D array A[][] of size N x 2 where:
- Every element lies between [1, N].
- A[i][0] signifies that there must be at most A[i][0] elements strictly lesser than i+1 and at most A[i][1] elements strictly greater than i+1.
The task is to find the maximum number of elements that can come together abiding by the above condition.
Examples:
Input: N = 3, A[][] = {{1, 2}, {2, 1}, {1, 1]}
Output: 2
Explanation: If 1, 2, 3 all come together, then there is 0 (at most 1) element less than 1 and 2(at most 2) are greater.
1(at most 2) element less than 2 and 1(at most 1) greater 2.
For 3 there are 2 elements less than 3 but as per the condition there can be at most 1 element smaller than 3.
So cannot include 3. Therefore maximum 2 elements can be selected together.
Input: N = 5, A[][] = {{2, 3}, {4, 2}, {3, 1}, {3, 1}, {1, 1}};
Output: 4
Naive Approach: The idea is based on the concept that a minimum of 1 element can be kept in a set and at max, all the elements can be kept together, i.e., N
- Initially, for the value of K where 1 <= K <= N, check if K elements can be grouped together abiding by the conditions.
- Select K elements out of N elements and check the below condition for all K from 1 to N.
- Check for every candidate i from 1 to N:
- If C candidates already belong to the set of K elements then for the ith element to belong in a set of K numbers, i must have exactly C elements smaller and K-C-1 elements greater than i.
- In this way, count the valid candidates and check if it is possible to keep K elements together in a set.
- At the end, the maximum K is the answer.
Time Complexity: O(N2)
Auxiliary Space: O(1)
Efficient Approach: The better approach is to solve using Binary Search.
- Instead of checking for every possible value of K use Binary Search there.
- As if it is possible to keep K elements together, this means it is also possible to keep any lower value of K elements together.
- So check for the higher values and if it is not possible to keep K elements together means higher values of K cannot be grouped together.
- When both lower and higher value becomes that is the answer.
Below is the implementation of the above-mentioned approach :
C++14
#include <bits/stdc++.h>
using namespace std;
bool isPossible(vector<vector< int > >& a,
int n, int k)
{
int candidatePresent = 0;
for ( int i = 0; i < n; i++) {
if (a[i][0] >= candidatePresent
&& a[i][1] >= k - candidatePresent
- 1)
candidatePresent++;
}
if (candidatePresent >= k)
return true ;
return false ;
}
int maxElementsinSet(vector<vector< int > >& a,
int n)
{
int left = 1, right = n;
int ans = 1;
while (left <= right) {
int mid = (left + right) / 2;
if (isPossible(a, n, mid)) {
ans = mid;
left = mid + 1;
}
else
right = mid - 1;
}
return ans;
}
int main()
{
int N = 5;
vector<vector< int > > A = {
{ 2, 3 }, { 4, 2 }, { 3, 1 }, { 3, 1 }, { 1, 1 }
};
cout << maxElementsinSet(A, N);
return 0;
}
|
Java
import java.util.*;
public class GFG {
static boolean isPossible( int a[][], int n, int k)
{
int candidatePresent = 0 ;
for ( int i = 0 ; i < n; i++) {
if (a[i][ 0 ] >= candidatePresent
&& a[i][ 1 ] >= k - candidatePresent - 1 )
candidatePresent++;
}
if (candidatePresent >= k)
return true ;
return false ;
}
static int maxElementsinSet( int a[][], int n)
{
int left = 1 , right = n;
int ans = 1 ;
while (left <= right) {
int mid = (left + right) / 2 ;
if (isPossible(a, n, mid) == true ) {
ans = mid;
left = mid + 1 ;
}
else
right = mid - 1 ;
}
return ans;
}
public static void main(String arg[])
{
int N = 5 ;
int A[][] = {
{ 2 , 3 }, { 4 , 2 }, { 3 , 1 }, { 3 , 1 }, { 1 , 1 }
};
System.out.println(maxElementsinSet(A, N));
}
}
|
Python
def isPossible(a, n, k):
candidatePresent = 0
for i in range (n):
if (a[i][ 0 ] > = candidatePresent
and a[i][ 1 ] > = k - candidatePresent
- 1 ):
candidatePresent + = 1
if (candidatePresent > = k):
return 1
return 0
def maxElementsinSet(a, n):
left = 1
right = n
ans = 1
while (left < = right):
mid = (left + right) / 2
if (isPossible(a, n, mid)):
ans = mid
left = mid + 1
else :
right = mid - 1
print (ans)
if __name__ = = "__main__" :
N = 5 ;
A = [[ 2 , 3 ], [ 4 , 2 ], [ 3 , 1 ], [ 3 , 1 ], [ 1 , 1 ]]
maxElementsinSet(A, N)
|
C#
using System;
public class GFG {
static bool isPossible( int [, ] a, int n, int k)
{
int candidatePresent = 0;
for ( int i = 0; i < n; i++) {
if (a[i, 0] >= candidatePresent
&& a[i, 1] >= k - candidatePresent - 1)
candidatePresent++;
}
if (candidatePresent >= k)
return true ;
return false ;
}
static int maxElementsinSet( int [, ] a, int n)
{
int left = 1, right = n;
int ans = 1;
while (left <= right) {
int mid = (left + right) / 2;
if (isPossible(a, n, mid) == true ) {
ans = mid;
left = mid + 1;
}
else
right = mid - 1;
}
return ans;
}
public static void Main(String[] arg)
{
int N = 5;
int [, ] A = {
{ 2, 3 }, { 4, 2 }, { 3, 1 }, { 3, 1 }, { 1, 1 }
};
Console.WriteLine(maxElementsinSet(A, N));
}
}
|
Javascript
<script>
const isPossible = (a, n, k) => {
let candidatePresent = 0;
for (let i = 0; i < n; i++) {
if (a[i][0] >= candidatePresent
&& a[i][1] >= k - candidatePresent
- 1)
candidatePresent++;
}
if (candidatePresent >= k)
return true ;
return false ;
}
const maxElementsinSet = (a, n) => {
let left = 1, right = n;
let ans = 1;
while (left <= right) {
let mid = parseInt((left + right) / 2);
if (isPossible(a, n, mid)) {
ans = mid;
left = mid + 1;
}
else
right = mid - 1;
}
return ans;
}
let N = 5;
let A = [
[2, 3], [4, 2], [3, 1], [3, 1], [1, 1]
];
document.write(maxElementsinSet(A, N));
</script>
|
Time Complexity: O(N*logN)
Auxiliary Space: O(1)
Share your thoughts in the comments
Please Login to comment...