Maximize count of pairs (i, j) from two arrays having element from first array not exceeding that from second array

Last Updated : 20 Feb, 2023
Comments
Improve
Suggest changes
Like Article
Like
Report

Given two arrays arr1[] and arr2[] of lengths N and M respectively, the task is to find the maximum number of pairs (i, j) such that 2 * arr1[i] ≤ arr2[j] (1 ≤ i ≤ N and 1 ≤ j ≤ M).

Note: Any array element can be part of a single pair.

Examples:

Input: N = 3, arr1[] = {3, 2, 1}, M = 4, arr2[] = {3, 4, 2, 1}
Output: 2
Explanation:
Only two pairs can be chosen:

  • (1, 3): Choose elements arr1[3] and arr2[1].
    Therefore, pair = (arr1[3], arr2[1]) = (1, 3). Also, 2 * arr1[3] ≤ arr2[1].
    Now elements at positions 3 and 1 of arr1[] and arr2[] respectively, cannot be chosen.
  • (2, 2): Choose elements arr1[2] and arr2[2].
    Therefore, pair = (arr1[2], arr2[2]) = (2, 4). Also, 2*arr1[2] <= arr2[2].
    Now elements at position 2 of arr1[] and arr2[] cannot be chosen.

Input: N = 1, arr1[] = {40}, M = 4, arr2[] = {10, 20, 30, 40}
Output: 0
Explanation: 
No Possible Pair exists which satisfies the condition.

 

Naive Approach: The simplest approach is to first sort both the arrays and for each element arr1[i], greedily find the element that is just greater than or equal to the value 2 * arr1[i] in the given array arr2[] and then remove that element from arr2[] by incrementing the total number of required pairs by 1. After traversing the whole array arr1[], print the number of pairs.

Time Complexity: O(N * M), where N and M are the lengths of the given array.
Auxiliary Space: O(N+M)

Efficient Approach: The idea is to use the Greedy Algorithm by finding an element in arr2[] that is just greater than or equal to the value 2*arr1[i] where 0<=i<=N-1. Follow the below steps to solve the problem:

  1. Sort the array arr1[] and initialize a variable ans to store the maximum number of pairs.
  2. Add all the elements of arr2[] in Max Heap.
  3. Traverse the array arr1[] from i = (N - 1) to 0 in non-increasing order.
  4. For each element arr1[i], remove the peek element from the Max Heap until 2*arr1[i] becomes smaller than or equal to the peek element and increment ans by 1 if such element is found.
  5. After traversing the whole array, print ans as the maximum number of pairs.

Below is the implementation of the above approach:

C++
// C++ program for the above approach

#include <bits/stdc++.h>
using namespace std;

// Function to return the maximum
// number of required pairs
int numberOfPairs(int arr1[], int n,
                  int arr2[], int m)
{

    // Max Heap to add values of arar2[]
    priority_queue<int> pq;
    int i, j;

    // Sort the array arr1[]
    sort(arr1, arr1 + n);

    // Push all arr2[] into Max Heap
    for (j = 0; j < m; j++) {
        pq.push(arr2[j]);
    }

    // Initialize the ans
    int ans = 0;

    // Traverse the arr1[] in
    // decreasing order
    for (i = n - 1; i >= 0; i--) {

        // Remove element until a
        // required pair is found
        if (pq.top() >= 2 * arr1[i]) {
            ans++;
          
            pq.pop();
        }
    }

    // Return maximum number of pairs
    return ans;
}

// Driver Code
int main()
{
    // Given arrays
    int arr1[] = { 3, 1, 2 };
    int arr2[] = { 3, 4, 2, 1 };

    int N = sizeof(arr1) / sizeof(arr1[0]);
    int M = sizeof(arr2) / sizeof(arr2[0]);

    // Function Call
    cout << numberOfPairs(arr1, N,
                          arr2, M);
    return 0;
}
Java
// Java program for the above approach
import java.io.*;
import java.util.*;

class GFG{
 
// Function to return the maximum
// number of required pairs
static int numberOfPairs(int[] arr1, int n, 
                         int[] arr2, int m)
{
    
    // Max Heap to add values of arr2[]
    PriorityQueue<Integer> pQueue = 
    new PriorityQueue<Integer>(
        new Comparator<Integer>()
    {
        public int compare(Integer lhs,
                           Integer rhs)
        {
            if (lhs < rhs)
            {
                return + 1;
            }
            if (lhs.equals(rhs))
            {
                return 0;
            }
            return -1;
        }
    });
    
    int i, j;
    
    // Sort the array arr1[]
    Arrays.sort(arr1);
    
    // Push all arr2[] into Max Heap
    for(j = 0; j < m; j++) 
    {
        pQueue.add(arr2[j]);
    }
    
    // Initialize the ans
    int ans = 0;
    
    // Traverse the arr1[] in
    // decreasing order
    for(i = n - 1; i >= 0; i--)
    {
        
        // Remove element until a
        // required pair is found
        if (pQueue.peek() >= 2 * arr1[i]) 
        {
            ans++;
            pQueue.poll();
        }
    }
    
    // Return maximum number of pairs
    return ans;
}

// Driver Code 
public static void main (String[] args)
{
    
    // Given arrays
    int[] arr1 = { 3, 1, 2 };
    int[] arr2 = { 3, 4, 2, 1 };
    
    int N = 3;
    int M = 4;
    
    // Function call
    System.out.println(numberOfPairs(arr1, N, 
                                     arr2, M));
}
}

// This code is contributed by sallagondaavinashreddy7
Python3
  # Python3 program for the above approach

  # Function to return the maximum
  # number of required pairs
  def numberOfPairs(arr1, n, arr2, m):

      # Max Heap to add values of arr2[]
      pq = []

      # Sort the array arr1[]
      arr1.sort(reverse = False)

      # Push all arr2[] into Max Heap
      for j in range(m):
          pq.append(arr2[j])

      # Initialize the ans
      ans = 2

      # Traverse the arr1[] in
      # decreasing order
      i = n - 1
      while (i >= 0):

          # Remove element until a
          # required pair is found
          pq.sort(reverse = False)

          if (pq[0] >= 2 * arr1[i]):
              ans += 1
              print(pq[0])
              pq.remove(pq[0])

          i -= 1

      # Return maximum number of pairs
      return ans

  # Driver Code
  if __name__ == '__main__':

      # Given arrays
      arr1 = [ 3, 2, 1 ]
      arr2 = [ 3, 4, 2, 1 ]

      N = len(arr1)
      M = len(arr2)

      # Function Call
      print(numberOfPairs(arr1, N, arr2, M))

  # This code is contributed by ipg2016107
C#
using System;
using System.Collections.Generic;

class Program 
{

  // Function to return the maximum
  // number of required pairs
  static int numberOfPairs(int[] arr1, int n, int[] arr2, int m) {

    // Max Heap to add values of arr2[]
    List<int> pq = new List<int>();

    // Sort the array arr1[]
    Array.Sort(arr1);

    // Push all arr2[] into Max Heap
    for (int j = 0; j < m; j++) {
      pq.Add(arr2[j]);
    }

    // Initialize the ans
    int ans = 2;

    // Traverse the arr1[] in decreasing order
    int i = n - 1;
    while (i >= 0) {
      // Remove element until a required pair is found
      pq.Sort();
      if (pq[0] >= 2 * arr1[i]) {
        ans += 1;
        Console.WriteLine(pq[0]);
        pq.Remove(pq[0]);
      }
      i -= 1;
    }

    // Return maximum number of pairs
    return ans;
  }

  static void Main(string[] args) {
    // Given arrays
    int[] arr1 = new int[] { 3, 2, 1 };
    int[] arr2 = new int[] { 3, 4, 2, 1 };

    int N = arr1.Length;
    int M = arr2.Length;

    // Function Call
    Console.WriteLine(numberOfPairs(arr1, N, arr2, M));
  }
}
JavaScript
<script>

// JavaScript program for the above approach

// Function to return the maximum
// number of required pairs
function numberOfPairs(arr1, n, arr2, m){
  
    // Max Heap to add values of arr2[]
    let pq = []

    // Sort the array arr1[]
    arr1.sort((a,b)=>a-b)

    // Push all arr2[] into Max Heap
    for(let j=0;j<m;j++)
        pq.push(arr2[j])

    // Initialize the ans
    let ans = 2

    // Traverse the arr1[] in
    // decreasing order
    let i = n - 1
    while (i >= 0){
      
        // Remove element until a
        // required pair is found
        pq.sort((a,b)=>a-b)
        
        if (pq[0] >= 2 * arr1[i]){
            ans += 1
            pq.shift()
        }
            
        i -= 1
    }

    // Return maximum number of pairs
    return ans
}

// Driver Code
  
// Given arrays
let arr1 = [ 3, 2, 1 ]
let arr2 = [ 3, 4, 2, 1 ]

let N = arr1.length
let M = arr2.length

// Function Call
document.write(numberOfPairs(arr1, N, arr2, M))

// This code is contributed by shinjanpatra

</script>

Output: 
2

 

Time Complexity: O(N*log N + M*log M), where N and M are the lengths of the given array.
Auxiliary Space: O(N+M)


Next Article

Similar Reads