Skip to content
Related Articles
Get the best out of our app
GFG App
Open App
geeksforgeeks
Browser
Continue

Related Articles

Maximize numbers that can be grouped together based on given conditions

Improve Article
Save Article
Like Article
Improve Article
Save Article
Like Article

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




// C++ code to implement the approach
 
#include <bits/stdc++.h>
using namespace std;
 
// Function to check if it is possible
// to keep k elements together
bool isPossible(vector<vector<int> >& a,
                int n, int k)
{
    // Initially the set is empty, so
    // candidates present is 0
    int candidatePresent = 0;
 
    // Loop through all the candidates
    for (int i = 0; i < n; i++) {
 
        // For i to be a part of the set
        // i's condition must allow to keep
        // Atleast candidatePresent number of
 
        // Elements smaller than i
        // And k-candidatePresent-1
        // Number of elements larger than i
 
        // If so then add i
        // To the set of k numbers
        if (a[i][0] >= candidatePresent
            && a[i][1] >= k - candidatePresent
                              - 1)
            candidatePresent++;
    }
 
    // If possible to keep at least k
    // elements together return true
    if (candidatePresent >= k)
        return true;
 
    // Else return false
    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 it is possible to keep mid
        // elements together them mid
        // is a possible answer and also
        // check for higher values of mid
        if (isPossible(a, n, mid)) {
            ans = mid;
            left = mid + 1;
        }
 
        // Else check for lower values of mid
        else
            right = mid - 1;
    }
 
    return ans;
}
 
// Driver Code
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




// Java code to implement the approach
import java.util.*;
public class GFG {
 
  // Function to check if it is possible
  // to keep k elements together
  static boolean isPossible(int a[][], int n, int k)
  {
 
    // Initially the set is empty, so
    // candidates present is 0
    int candidatePresent = 0;
 
    // Loop through all the candidates
    for (int i = 0; i < n; i++) {
 
      // For i to be a part of the set
      // i's condition must allow to keep
      // Atleast candidatePresent number of
 
      // Elements smaller than i
      // And k-candidatePresent-1
      // Number of elements larger than i
 
      // If so then add i
      // To the set of k numbers
      if (a[i][0] >= candidatePresent
          && a[i][1] >= k - candidatePresent - 1)
        candidatePresent++;
    }
 
    // If possible to keep at least k
    // elements together return true
    if (candidatePresent >= k)
      return true;
 
    // Else return false
    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 it is possible to keep mid
      // elements together them mid
      // is a possible answer and also
      // check for higher values of mid
      if (isPossible(a, n, mid) == true) {
        ans = mid;
        left = mid + 1;
      }
 
      // Else check for lower values of mid
      else
        right = mid - 1;
    }
 
    return ans;
  }
 
  // Driver Code
  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));
  }
}
 
// This code is contributed by Samim Hossain Mondal.


Python




# Python code to implement the approach
 
# Function to check if it is possible
# to keep k elements together
def isPossible(a, n, k):
 
    # Initially the set is empty, so
    # candidates present is 0
    candidatePresent = 0
 
    # Loop through all the candidates
    for i in range(n):
 
        # For i to be a part of the set
        # i's condition must allow to keep
        # Atleast candidatePresent number of
 
        # Elements smaller than i
        # And k-candidatePresent-1
        # Number of elements larger than i
 
        # If so then add i
        # To the set of k numbers
        if (a[i][0] >= candidatePresent
            and a[i][1] >= k - candidatePresent
                              - 1):
            candidatePresent += 1
     
 
    # If possible to keep at least k
    # elements together return true
    if (candidatePresent >= k):
        return 1
 
    # Else return false
    return 0
 
def maxElementsinSet(a, n):
    left = 1
    right = n
    ans = 1
 
    while (left <= right):
        mid = (left + right) / 2
 
        # If it is possible to keep mid
        # elements together them mid
        # is a possible answer and also
        # check for higher values of mid
        if (isPossible(a, n, mid)):
            ans = mid
            left = mid + 1
 
        # Else check for lower values of mid
        else:
            right = mid - 1
 
    print(ans)
 
# Driver Code
if __name__ == "__main__":
   
    N = 5;
    A = [[ 2, 3 ], [ 4, 2 ], [ 3, 1 ], [ 3, 1 ], [ 1, 1 ]]
 
    maxElementsinSet(A, N)
     
    # This code is contributed by hrithikgarg03188.


C#




// C# code to implement the approach
using System;
 
public class GFG {
 
  // Function to check if it is possible
  // to keep k elements together
  static bool isPossible(int[, ] a, int n, int k)
  {
 
    // Initially the set is empty, so
    // candidates present is 0
    int candidatePresent = 0;
 
    // Loop through all the candidates
    for (int i = 0; i < n; i++) {
 
      // For i to be a part of the set
      // i's condition must allow to keep
      // Atleast candidatePresent number of
 
      // Elements smaller than i
      // And k-candidatePresent-1
      // Number of elements larger than i
 
      // If so then add i
      // To the set of k numbers
      if (a[i, 0] >= candidatePresent
          && a[i, 1] >= k - candidatePresent - 1)
        candidatePresent++;
    }
 
    // If possible to keep at least k
    // elements together return true
    if (candidatePresent >= k)
      return true;
 
    // Else return false
    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 it is possible to keep mid
      // elements together them mid
      // is a possible answer and also
      // check for higher values of mid
      if (isPossible(a, n, mid) == true) {
        ans = mid;
        left = mid + 1;
      }
 
      // Else check for lower values of mid
      else
        right = mid - 1;
    }
 
    return ans;
  }
 
  // Driver Code
  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));
  }
}
 
// This code is contributed by shikhasingrajput


Javascript




<script>
    // JavaScript code to implement the approach
 
    // Function to check if it is possible
    // to keep k elements together
    const isPossible = (a, n, k) => {
     
        // Initially the set is empty, so
        // candidates present is 0
        let candidatePresent = 0;
 
        // Loop through all the candidates
        for (let i = 0; i < n; i++) {
 
            // For i to be a part of the set
            // i's condition must allow to keep
            // Atleast candidatePresent number of
 
            // Elements smaller than i
            // And k-candidatePresent-1
            // Number of elements larger than i
 
            // If so then add i
            // To the set of k numbers
            if (a[i][0] >= candidatePresent
                && a[i][1] >= k - candidatePresent
                - 1)
                candidatePresent++;
        }
 
        // If possible to keep at least k
        // elements together return true
        if (candidatePresent >= k)
            return true;
 
        // Else return false
        return false;
    }
 
    const maxElementsinSet = (a, n) => {
        let left = 1, right = n;
        let ans = 1;
 
        while (left <= right) {
            let mid = parseInt((left + right) / 2);
 
            // If it is possible to keep mid
            // elements together them mid
            // is a possible answer and also
            // check for higher values of mid
            if (isPossible(a, n, mid)) {
                ans = mid;
                left = mid + 1;
            }
 
            // Else check for lower values of mid
            else
                right = mid - 1;
        }
 
        return ans;
    }
 
    // Driver Code
    let N = 5;
    let A = [
        [2, 3], [4, 2], [3, 1], [3, 1], [1, 1]
    ];
 
    document.write(maxElementsinSet(A, N));
 
// This code is contributed by rakeshsahni
 
</script>


Output

4

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


My Personal Notes arrow_drop_up
Last Updated : 21 Jul, 2022
Like Article
Save Article
Similar Reads
Related Tutorials