Related Articles
Maximize value of a pair from two given arrays based on given conditions
• Last Updated : 09 Feb, 2021

Given two arrays A[] and B[] consisting of N integers and an integer K, the task is to find the maximum value of B[i] + B[j] + abs(A[i] – A[j]) by choosing any pair (i, j) such that abs(A[i] – A[j]) ≤ K.

Examples:

Input: A[] = {5, 6, 9, 10}, B[] = {3, 0, 10, -10}, K = 1
Output: 4
Explanation:
Only two pairs can be chosen, i.e. (0, 1) and (2, 3), because abs(A – A) ≤ K and abs(A – A) ≤ K.
The value of (0, 1) pair is B + B + abs(A – A) = 3 + 0 + 1 = 4.
The value of (2, 3) pair is B + B + abs(A – A) = 10 + (-10) + 1 = 1.
Hence, the maximum value from all possible pairs is 4.

Input: A[] = {1, 2, 3, 4}, B[] = {0, 8, 6, 9}, K = 2
Output: 19

Naive Approach: The simplest approach is to generate all possible pairs from the given array and count those pairs that satisfy the given conditions. After checking all the pairs print the count of all pairs.

Time Complexity: O(N2)
Auxiliary Space: O(N)

Efficient Approach: To optimize the above approach, the idea is to use Segment Trees, Binary Search, and Sorting of the array according to the value of array A[]. Observe that, from the given equation it is clear that B[i] + B[j] + abs(A[i] – A[j]) equals to any of the below values:

• B[i] + B[j] + (A[i] – A[j])
• B[i] + B[j] + (A[j] – A[i])

Consider 2nd equation:

B[i] + B[j] + A[j] – A[i] = B[i] – A[i] + (B[j] + A[j])

• Here, it is observed that for each i in the array A[], finding the right most index of value smaller than of equal to A[i] + K. Let the rightmost index be right.
• Now, calculate B[i] – A[i] + max value of B[j] + A[j] where i + 1 <= j <= right. This will give the maximum value of selected pair.
• To calculate the maximum value each time in a range, segment trees can be used.

Follow the below steps to solve the problem:

• Sort all values, B[i] and B[i] + A[i] according to the values of array A[].
• Initialize maxValue as INT_MIN to store the final maximum answer and initialize a range maximum query segment tree storing all values, A[i] + B[i].
• Traverse the array A[] and perform the following:
• For each element find the index, say right, such that abs(A[i] – A[right]) <= K using Binary Search.
• Then, find the maximum value, of (A[j] + B[j]) where i+1 <= j <= right.
• Update maxValue as maxValue = max(maxValue, B[i] – A[i] + A[j] + B[j]).
• After the above steps, print the value of maxValue as the result.

Below is the implementation of the above approach:

## Java

 `// Java program for the above approach` `import` `java.util.*;` `// Clas to store the values of a[i],``// b[i], a[i] + b[i]``class` `triplet ``implements` `Comparable {` `    ``int` `a, b, c;` `    ``// Constructor``    ``triplet(``int` `a, ``int` `b, ``int` `c)``    ``{``        ``this``.a = a;``        ``this``.b = b;``        ``this``.c = c;``    ``}` `    ``// Sort values according to array``    ``public` `int` `compareTo(triplet o)``    ``{``        ``return` `this``.a - o.a;``    ``}``}` `class` `GFG {` `    ``// Stores the segment tree``    ``static` `int` `seg[];` `    ``// Function to find the maximum``    ``// possible value according to the``    ``// given condition``    ``public` `static` `void` `maxValue(``        ``int` `a[], ``int` `b[], ``int` `n, ``int` `k)``    ``{``        ``// Initialize triplet array``        ``triplet arr[] = ``new` `triplet[n];` `        ``// Store the values a[i], b[i],``        ``// a[i] + b[i]``        ``for` `(``int` `i = ``0``; i < n; i++) {` `            ``arr[i] = ``new` `triplet(a[i], b[i],``                                 ``a[i] + b[i]);``        ``}` `        ``// Sort the array according``        ``// to array a[]``        ``Arrays.sort(arr);` `        ``// Build segment tree``        ``seg = ``new` `int``[``4` `* n];``        ``build(arr, ``0``, ``0``, n - ``1``);` `        ``// Intialise the maxvalue of``        ``// the selected pairs``        ``int` `maxvalue = Integer.MIN_VALUE;` `        ``// Traverse the array``        ``for` `(``int` `i = ``0``; i < n; i++) {` `            ``// For each value find the``            ``// floor(arr[i] + k)``            ``int` `right = search(arr,``                               ``arr[i].a + k);` `            ``// Find the maximum value of``            ``// the select pairs i and max``            ``// from (i + 1, right)``            ``if` `(right != -``1``) {` `                ``maxvalue = Math.max(``                    ``maxvalue, arr[i].b - arr[i].a``                                  ``+ getMax(arr, ``0``, ``0``, n - ``1``,``                                           ``i + ``1``, right));``            ``}``        ``}` `        ``// Print the maximum value``        ``System.out.println(maxvalue);``    ``}` `    ``// Function to search floor of``    ``// the current value``    ``public` `static` `int` `search(``        ``triplet arr[], ``int` `val)``    ``{``        ``// Initialise low and high values``        ``int` `low = ``0``, high = arr.length - ``1``;``        ``int` `ans = -``1``;` `        ``// Perform Binary Search``        ``while` `(low <= high) {``            ``int` `mid = low + (high - low) / ``2``;` `            ``// If the current value is``            ``// <= val then store the``            ``// candidate answer and``            ``// find for rigtmost one``            ``if` `(arr[mid].a <= val) {``                ``ans = mid;``                ``low = mid + ``1``;``            ``}``            ``else``                ``high = mid - ``1``;``        ``}``        ``return` `ans;``    ``}` `    ``// Function to build segment tree``    ``public` `static` `void` `build(``        ``triplet arr[], ``int` `index,``        ``int` `s, ``int` `e)``    ``{``        ``// Base Case``        ``if` `(s == e) {``            ``seg[index] = arr[s].c;``            ``return``;``        ``}``        ``int` `mid = s + (e - s) / ``2``;` `        ``// Build the left and right``        ``// segment trees``        ``build(arr, ``2` `* index + ``1``, s, mid);``        ``build(arr, ``2` `* index + ``2``, mid + ``1``, e);` `        ``// Update current index``        ``seg[index] = Math.max(seg[``2` `* index + ``1``],``                              ``seg[``2` `* index + ``2``]);``    ``}` `    ``// Function to get maximum value``    ``// in the range [qs, qe]``    ``public` `static` `int` `getMax(``        ``triplet arr[], ``int` `index, ``int` `s,``        ``int` `e, ``int` `qs, ``int` `qe)``    ``{``        ``// If segement is not in range``        ``if` `(qe < s || e < qs)``            ``return` `Integer.MIN_VALUE / ``2``;` `        ``// If segement is completely``        ``// inside the query``        ``if` `(s >= qs && e <= qe)``            ``return` `seg[index];` `        ``// Calcualate the maximum value``        ``// in left and right half``        ``int` `mid = s + (e - s) / ``2``;``        ``return` `Math.max(``            ``getMax(arr, ``2` `* index + ``1``,``                   ``s, mid, qs, qe),``            ``getMax(arr, ``2` `* index + ``2``,``                   ``mid + ``1``, e, qs, qe));``    ``}` `    ``// Driver Code``    ``public` `static` `void` `main(String args[])``    ``{``        ``int` `N = ``4``, K = ``1``;``        ``int` `A[] = { ``5``, ``6``, ``9``, ``10` `};``        ``int` `B[] = { ``3``, ``0``, ``10``, -``10` `};` `        ``// Function call``        ``maxValue(A, B, N, K);``    ``}``}`

## C#

 `// C# program for the above approach``using` `System;``using` `System.Collections.Generic;` `// Clas to store the values of a[i],``// b[i], a[i] + b[i]``public` `class` `triplet : IComparable {` `    ``public` `int` `a, b, c;` `    ``// Constructor``    ``public` `triplet(``int` `a, ``int` `b, ``int` `c)``    ``{``        ``this``.a = a;``        ``this``.b = b;``        ``this``.c = c;``    ``}` `    ``// Sort values according to array``    ``public` `int` `CompareTo(triplet o)``    ``{``        ``return` `this``.a - o.a;``    ``}``}` `public` `class` `GFG {` `    ``// Stores the segment tree``    ``static` `int` `[]seg;` `    ``// Function to find the maximum``    ``// possible value according to the``    ``// given condition``    ``public`  `void` `maxValue(``        ``int` `[]a, ``int` `[]b, ``int` `n, ``int` `k)``    ``{``        ``// Initialize triplet array``        ``triplet []arr = ``new` `triplet[n];` `        ``// Store the values a[i], b[i],``        ``// a[i] + b[i]``        ``for` `(``int` `i = 0; i < n; i++) {` `            ``arr[i] = ``new` `triplet(a[i], b[i],``                                 ``a[i] + b[i]);``        ``}` `        ``// Sort the array according``        ``// to array []a``        ``Array.Sort(arr);` `        ``// Build segment tree``        ``seg = ``new` `int``[4 * n];``        ``build(arr, 0, 0, n - 1);` `        ``// Intialise the maxvalue of``        ``// the selected pairs``        ``int` `maxvalue = ``int``.MinValue;` `        ``// Traverse the array``        ``for` `(``int` `i = 0; i < n; i++) {`` ` `            ``// For each value find the``            ``// floor(arr[i] + k)``            ``int` `right = search(arr,``                               ``arr[i].a + k);` `            ``// Find the maximum value of``            ``// the select pairs i and max``            ``// from (i + 1, right)``            ``if` `(right != -1) {` `                ``maxvalue = Math.Max(``                    ``maxvalue, arr[i].b - arr[i].a``                                  ``+ getMax(arr, 0, 0, n - 1,``                                           ``i + 1, right));``            ``}``        ``}` `        ``// Print the maximum value``        ``Console.WriteLine(maxvalue);``    ``}` `    ``// Function to search floor of``    ``// the current value ``    ``public` `int` `search(``        ``triplet []arr, ``int` `val)``    ``{``        ``// Initialise low and high values``        ``int` `low = 0, high = arr.Length - 1;``        ``int` `ans = -1;` `        ``// Perform Binary Search``        ``while` `(low <= high) {``            ``int` `mid = low + (high - low) / 2;` `            ``// If the current value is``            ``// <= val then store the``            ``// candidate answer and``            ``// find for rigtmost one``            ``if` `(arr[mid].a <= val) {``                ``ans = mid;``                ``low = mid + 1;``            ``}``            ``else``                ``high = mid - 1;``        ``}``        ``return` `ans;``    ``}` `    ``// Function to build segment tree``    ``public` `static` `void` `build(``        ``triplet []arr, ``int` `index,``        ``int` `s, ``int` `e)``    ``{``        ``// Base Case``        ``if` `(s == e) {``            ``seg[index] = arr[s].c;``            ``return``;``        ``}``        ``int` `mid = s + (e - s) / 2;` `        ``// Build the left and right``        ``// segment trees``        ``build(arr, 2 * index + 1, s, mid);``        ``build(arr, 2 * index + 2, mid + 1, e);` `        ``// Update current index``        ``seg[index] = Math.Max(seg[2 * index + 1],``                              ``seg[2 * index + 2]);``    ``}` `    ``// Function to get maximum value``    ``// in the range [qs, qe]``    ``public` `static` `int` `getMax(``        ``triplet []arr, ``int` `index, ``int` `s,``        ``int` `e, ``int` `qs, ``int` `qe)``    ``{``        ``// If segement is not in range``        ``if` `(qe < s || e < qs)``            ``return` `int``.MinValue / 2;` `        ``// If segement is completely``        ``// inside the query``        ``if` `(s >= qs && e <= qe)``            ``return` `seg[index];` `        ``// Calcualate the maximum value``        ``// in left and right half``        ``int` `mid = s + (e - s) / 2;``        ``return` `Math.Max(``            ``getMax(arr, 2 * index + 1,``                   ``s, mid, qs, qe),``            ``getMax(arr, 2 * index + 2,``                   ``mid + 1, e, qs, qe));``    ``}` `    ``// Driver Code``    ``public` `static` `void` `Main(String []args)``    ``{``        ``int` `N = 4, K = 1;``        ``int` `[]A = { 5, 6, 9, 10 };``        ``int` `[]B = { 3, 0, 10, -10 };` `        ``// Function call``        ``new` `GFG().maxValue(A, B, N, K);``    ``}``}` `// This code is contributed by 29AjayKumar`

Output:
`4`

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

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

My Personal Notes arrow_drop_up