GFG App
Open App
Browser
Continue

# Find the pairs of IDs from two arrays having sum less than target closest to it

Given two arrays arr1[] and arr2[] of pairs of the form {ID, value} of size N and M respectively and an integer target, the task is to find all the pairs of IDs from both the arrays such that the sum of the values of the pairs is maximum and has a value at most M.

Examples:

Input: arr1[] = [[1, 2000], [2, 3000], [3, 2000]], arr2[] = [[1, 2500], [2, 3000], [3, 3000]], target = 6000
Output:
2 2
2 3
Explanation:
Following are the pairs of elements from the two arrays arr1[] and arr2[]:

• (arr1[2], arr2[2]): The sum of elements 3000 + 3000 = 6000(= target) and closest to the value target. Print the IDs as (2, 2).
• (arr1[2], arr2[3]): The sum of elements 3000 + 3000 = 6000(= target) and closest to the value target. Print the IDs as (2, 3).

Input: arr1[] = [[1, 2000], [2, 3000], [3, 2000]], arr2[] = [[1, 3000], [2, 3000]], target = 5500
Output:
1 1
1 2
3 1
3 2

## Recommended: Please try your approach on {IDE} first, before moving on to the solution.

Approach: The given problem can be solved using the TreeMap Data Structure to store the array elements arr1[] and efficiently find the pair for every element in the other array arr2[]. Below are the steps:

• Create a TreeMap where the key is the value of the array element and the value is the list of IDs.
• Iterate the array arr1[] and insert its elements into the TreeMap.
• Initialize a variable, say closestTarget to keep track of the closest value to the target and not exceeding it.
• Initialize an ArrayList result to store all the possible pairs of IDs.
• Iterate the array arr2[] and for every element calculate the remaining value to be searched in the TreeMap.
• If the remaining value, say (target – arr2[i]) is less than 0, then the pair cannot be formed so continue the iteration.
• Use the floorKey() function of the TreeMap to find a value less than or equal to the remaining value. If the returned value of the above function is null, then no corresponding element is found.
• If the returned value, say currentTarget is greater than closestTarget, then update closestTarget and re-initialize the arrayList result[] to a new list.
• Iterate through the list of ids whose key is currentTarget and add all possible combinations of IDs pairs into the result list.
• After completing the above steps, print all the pairs of IDs stored in the ArrayList result[].

Below is the implementation of the above approach:

## C++

 `#include ` `using` `namespace` `std;`   `// Function to find pairs of ids with` `// sum of values closest to the target` `// but not exceeding the target` `void` `closestPair(vector > arr1, vector > arr2, ``int` `target)` `{` `    ``// Initialize map having array` `    ``// element value as key and list of` `    ``// ids as value in the map` `    ``map<``int``, vector<``int``> > valueToIds;`   `    ``// list to store all answer pairs` `    ``vector > result;`   `    ``// Keeps the track of maximum sum` `    ``// of pair values not exceeding target` `    ``int` `closestTarget = 0;`   `    ``// Iterate through the array arr1 and` `    ``// add all elements in the map` `    ``for` `(vector<``int``> a : arr1) {` `        ``int` `val = a[1], id = a[0];` `        ``if` `(valueToIds.find(val) == valueToIds.end())` `            ``valueToIds[val] = vector<``int``>();` `        ``valueToIds[val].push_back(id);` `    ``}`   `    ``for` `(vector<``int``> b : arr2) {` `        ``// Find the corresponding value` `        ``// to be found` `        ``int` `remaining = target - b[1];`   `        ``if` `(remaining < 0)` `            ``continue``;`   `        ``// Find a value which is close to` `        ``// desired value, not exceeding it` `        ``map<``int``, vector<``int``> >::iterator it = valueToIds.lower_bound(remaining);` `        ``if` `(it == valueToIds.end())` `            ``continue``;`   `        ``int` `floor` `= it->first;`   `        ``int` `currentTarget = b[1] + ``floor``;`   `        ``if` `(currentTarget >= closestTarget) {` `            ``if` `(currentTarget > closestTarget) {` `                ``// Update closestTarget and reset` `                ``// result list` `                ``closestTarget = currentTarget;` `                ``result.clear();` `            ``}`   `            ``// Add all possible pairs in` `            ``// result list` `            ``for` `(``int` `id : valueToIds[``floor``])` `                ``result.push_back({ id, b[0] });` `        ``}` `    ``}`   `    ``// Print all the id pairs` `    ``for` `(vector<``int``> ans : result) {` `        ``cout << ans[0] << ``" "` `<< ans[1] << endl;` `    ``}` `}`   `// Driver Code` `int` `main()` `{` `    ``vector > arr1` `        ``= { { 1, 2000 }, { 2, 3000 }, { 3, 2000 } };` `    ``vector > arr2 = { { 1, 3000 },` `                                   ``{ 2, 3000 } };` `    ``int` `target = 5500;`   `    ``closestPair(arr1, arr2, target);`   `    ``return` `0;` `}`

## Java

 `// Java program for the above approach`   `import` `java.io.*;` `import` `java.util.*;`   `class` `GFG {`   `    ``// Function to find pairs of ids with` `    ``// sum of values closest to the target` `    ``// but not exceeding the target` `    ``public` `static` `void` `closestPair(` `        ``int``[][] arr1, ``int``[][] arr2, ``int` `target)` `    ``{`   `        ``// Initialize TreeMap having array` `        ``// element value as key and list of` `        ``// ids as value in the TreeMap` `        ``TreeMap > valueToIds` `            ``= ``new` `TreeMap<>();`   `        ``// list to store all answer pairs` `        ``List<``int``[]> result = ``new` `ArrayList<>();`   `        ``// Keeps the track of maximum sum` `        ``// of pair values not exceeding target` `        ``int` `closestTarget = ``0``;`   `        ``// Iterate through the array arr1 and` `        ``// add all elements in the TreeMap` `        ``for` `(``int``[] a : arr1) {`   `            ``int` `val = a[``1``], id = a[``0``];` `            ``valueToIds.putIfAbsent(` `                ``val, ``new` `ArrayList<>());` `            ``valueToIds.get(val).add(id);` `        ``}`   `        ``for` `(``int``[] b : arr2) {`   `            ``// Find the corresponding value` `            ``// to be found` `            ``int` `remaining = target - b[``1``];`   `            ``if` `(remaining < ``0``)` `                ``continue``;`   `            ``// Find a value which is close to` `            ``// desired value, not exceeding it` `            ``Integer floor = valueToIds.floorKey(` `                ``remaining);`   `            ``// No value found which is less` `            ``// than or equal to floor` `            ``if` `(floor == ``null``)` `                ``continue``;`   `            ``int` `currentTarget = b[``1``] + floor;`   `            ``if` `(currentTarget >= closestTarget) {` `                ``if` `(currentTarget > closestTarget) {`   `                    ``// Update closeTarget and reset` `                    ``// result list` `                    ``closestTarget = currentTarget;` `                    ``result = ``new` `ArrayList<>();` `                ``}`   `                ``// Add all possible pairs in` `                ``// result list` `                ``for` `(``int` `id : valueToIds.get(floor))` `                    ``result.add(` `                        ``new` `int``[] { id, b[``0``] });` `            ``}` `        ``}`   `        ``// Print all the id pairs` `        ``for` `(``int``[] ans : result) {` `            ``System.out.println(` `                ``ans[``0``] + ``" "` `+ ans[``1``]);` `        ``}` `    ``}`   `    ``// Driver Code` `    ``public` `static` `void` `main(String[] args)` `    ``{` `        ``int``[][] arr1` `            ``= { { ``1``, ``2000` `}, { ``2``, ``3000` `}, { ``3``, ``2000` `} };` `        ``int``[][] arr2 = { { ``1``, ``3000` `},` `                         ``{ ``2``, ``3000` `} };` `        ``int` `target = ``5500``;`   `        ``closestPair(arr1, arr2, target);` `    ``}` `}`

## Python3

 `from` `bisect ``import` `bisect_right`   `def` `closestPair(arr1, arr2, target):` `    ``# Create a dictionary to store the array elements` `    ``value_to_ids ``=` `{}` `    ``for` `a ``in` `arr1:` `        ``val, ``id` `=` `a[``1``], a[``0``]` `        ``if` `val ``not` `in` `value_to_ids:` `            ``value_to_ids[val] ``=` `[]` `        ``value_to_ids[val].append(``id``)` `    ``# Create a list to store the closest pairs` `    ``closest_pairs ``=` `[]` `    ``closest_target ``=` `0` `    ``# Iterate through arr2` `    ``for` `b ``in` `arr2:` `        ``remaining ``=` `target ``-` `b[``1``]` `        ``if` `remaining < ``0``:` `            ``continue` `        ``# Find the closest value to remaining in value_to_ids` `        ``closest_val ``=` `bisect_right(``sorted``(value_to_ids.keys()), remaining)` `        ``if` `closest_val ``=``=` `0``:` `            ``continue` `        ``closest_val ``=` `sorted``(value_to_ids.keys())[closest_val ``-` `1``]` `        ``current_target ``=` `b[``1``] ``+` `closest_val` `        ``if` `current_target >``=` `closest_target:` `            ``if` `current_target > closest_target:` `                ``closest_target ``=` `current_target` `                ``closest_pairs ``=` `[]` `            ``for` `id` `in` `value_to_ids[closest_val]:` `                ``closest_pairs.append((``id``, b[``0``]))` `    ``# Print all the id pairs` `    ``for` `pair ``in` `closest_pairs:` `        ``print``(pair[``0``], pair[``1``])` `        `  `# Driver Code` `if` `__name__ ``=``=` `"__main__"``:` `    ``arr1 ``=` `[[``1``, ``2000``], [``2``, ``3000``], [``3``, ``2000``]]` `    ``arr2 ``=` `[[``1``, ``3000``], [``2``, ``3000``]]` `    ``target ``=` `5500`   `    ``closestPair(arr1, arr2, target)`

## C#

 `using` `System;` `using` `System.Collections.Generic;`   `class` `GFG ` `{` `  `  `  ``// Function to find pairs of ids with` `  ``// sum of values closest to the target` `  ``// but not exceeding the target` `  ``public` `static` `void` `closestPair(``int``[][] arr1, ` `                                 ``int``[][] arr2, ` `                                 ``int` `target)` `  ``{` `    `  `    ``// Initialize Dictionary having array` `    ``// element value as key and list of` `    ``// ids as value in the Dictionary` `    ``Dictionary<``int``, List<``int``>> valueToIds = ``new` `Dictionary<``int``, List<``int``>>();`   `    ``// list to store all answer pairs` `    ``List<``int``[]> result = ``new` `List<``int``[]>();`   `    ``// Keeps the track of maximum sum` `    ``// of pair values not exceeding target` `    ``int` `closestTarget = 0;`   `    ``// Iterate through the array arr1 and` `    ``// add all elements in the Dictionary` `    ``foreach` `(``int``[] a ``in` `arr1) {` `      ``int` `val = a[1], id = a[0];` `      ``if` `(!valueToIds.ContainsKey(val)) {` `        ``valueToIds[val] = ``new` `List<``int``>();` `      ``}` `      ``valueToIds[val].Add(id);` `    ``}`   `    ``foreach` `(``int``[] b ``in` `arr2) ` `    ``{` `      `  `      ``// Find the corresponding value` `      ``// to be found` `      ``int` `remaining = target - b[1];`   `      ``if` `(remaining < 0) {` `        ``continue``;` `      ``}`   `      ``// Find a value which is close to` `      ``// desired value, not exceeding it` `      ``int``? floor = ``null``;` `      ``foreach` `(``int` `key ``in` `valueToIds.Keys) {` `        ``if` `(key <= remaining) {` `          ``floor = floor == ``null` `? key : Math.Max(floor.Value, key);` `        ``}` `      ``}`   `      ``// No value found which is less` `      ``// than or equal to floor` `      ``if` `(floor == ``null``) {` `        ``continue``;` `      ``}`   `      ``int` `currentTarget = b[1] + floor.Value;`   `      ``if` `(currentTarget >= closestTarget) {` `        ``if` `(currentTarget > closestTarget) {` `          ``// Update closeTarget and reset` `          ``// result list` `          ``closestTarget = currentTarget;` `          ``result = ``new` `List<``int``[]>();` `        ``}`   `        ``// Add all possible pairs in` `        ``// result list` `        ``foreach` `(``int` `id ``in` `valueToIds[floor.Value]) {` `          ``result.Add(``new` `int``[] { id, b[0] });` `        ``}` `      ``}` `    ``}`   `    ``// Print all the id pairs` `    ``foreach` `(``int``[] ans ``in` `result) {` `      ``Console.WriteLine(ans[0] + ``" "` `+ ans[1]);` `    ``}` `  ``}`   `  ``// Driver Code` `  ``public` `static` `void` `Main(``string``[] args) {` `    ``int``[][] arr1 = ``new` `int``[][] {` `      ``new` `int``[] { 1, 2000 },` `      ``new` `int``[] { 2, 3000 },` `      ``new` `int``[] { 3, 2000 }` `    ``};` `    ``int``[][] arr2 = ``new` `int``[][] {` `      ``new` `int``[] { 1, 3000 },` `      ``new` `int``[] { 2, 3000 }` `    ``};` `    ``int` `target = 5500;`   `    ``closestPair(arr1, arr2, target);` `  ``}` `}`

## Javascript

 `function` `closestPair(arr1, arr2, target) ` `{`   `    ``// Create a dictionary to store the array elements` `    ``let value_to_ids = {};` `    ``for` `(let a of arr1) {` `        ``let val = a[1], id = a[0];` `        ``if` `(!value_to_ids[val]) {` `            ``value_to_ids[val] = [];` `        ``}` `        ``value_to_ids[val].push(id);` `    ``}` `    `  `    ``// Create a list to store the closest pairs` `    ``let closest_pairs = [];` `    ``let closest_target = 0;` `    `  `    ``// Iterate through arr2` `    ``for` `(let b of arr2) {` `        ``let remaining = target - b[1];` `        ``if` `(remaining < 0) {` `            ``continue``;` `        ``}` `        `  `        ``// Find the closest value to remaining in value_to_ids` `        ``let keys = Object.keys(value_to_ids).sort((a, b) => a - b);` `        ``let closest_val = keys.find(k => k >= remaining);` `        ``if` `(!closest_val) {` `            ``continue``;` `        ``}` `        ``let current_target = b[1] + closest_val;` `        ``if` `(current_target >= closest_target) {` `            ``if` `(current_target > closest_target) {` `                ``closest_target = current_target;` `                ``closest_pairs = [];` `            ``}` `            ``for` `(let id of value_to_ids[closest_val]) {` `                ``closest_pairs.push([id, b[0]]);` `            ``}` `        ``}` `    ``}` `    `  `    ``// Print all the id pairs` `    ``for` `(let pair of closest_pairs) {` `        ``console.log(pair[0], pair[1]);` `    ``}` `}`   `// Driver Code` `if` `(``typeof` `require === ``'undefined'` `|| require.main === module) {` `    ``let arr1 = [[1, 2000], [2, 3000], [3, 2000]];` `    ``let arr2 = [[1, 3000], [2, 3000]];` `    ``let target = 5500;`   `    ``closestPair(arr1, arr2, target);` `}`   `// This code is contributed by aadityamaharshi21.`

Output:

```1 1
3 1
1 2
3 2```

Time Complexity: O(N*log N + M)
Auxiliary Space: O(N*M)

My Personal Notes arrow_drop_up