Given three sorted arrays a[], b[] and c[], find the minimum value of max(abs(a[i] – b[j]), abs(b[j] – c[k]), abs(c[k] – a[i])). Here i, j and k are indexes in arrays a[], b[] and c[] respectively and abs() indicates absolute value.
Examples:Â
Input: a[] = [1, 4, 10], b[] = [2, 15, 20], c[] = [10, 12]
Output: 5
Explanation: We take 10 from a, 15 from b and 10 from c, so max(abs(10-15),abs(15-12),abs(10-10))is 5Input: a[] = [20, 24, 100], b[] = [2, 19, 22, 79, 800], c[] = [10, 12, 23, 24, 119]
Output: 2
Explanation: We take 24 from a, 22 from b and 24 from c. So max(abs(24-22), abs(24-22), abs(24-24))) is 2.
Table of Content
[Naive Approach] Checking Each Triplet - O(n1 * n2 * n3) Time and O(1) Space
The simplest approach is to try every possible combination of one element from each array.
For each combination, we calculate the three differences between the chosen elements and take the maximum of these differences. Among all combinations, the one that gives the smallest maximum difference is the answer, and the corresponding elements from the arrays are the triplet we choose.
#include <algorithm>
#include <climits>
#include <iostream>
#include <vector>
using namespace std;
int findClosest(vector<int> &a, vector<int> &b, vector<int> &c)
{
int n1 = a.size();
int n2 = b.size();
int n3 = c.size();
int minVal = INT_MAX;
// Try all possible triplets
for (int i = 0; i < n1; i++)
{
for (int j = 0; j < n2; j++)
{
for (int k = 0; k < n3; k++)
{
// Find maximum absolute difference
int curr = max({abs(a[i] - b[j]), abs(b[j] - c[k]), abs(c[k] - a[i])});
// Update minimum value
minVal = min(minVal, curr);
}
}
}
return minVal;
}
int main()
{
vector<int> a = {1, 4, 10};
vector<int> b = {2, 15, 20};
vector<int> c = {10, 12};
cout << findClosest(a, b, c);
return 0;
}
import java.util.Arrays;
public class GfG {
public static int findClosest(int[] a, int[] b, int[] c) {
int n1 = a.length;
int n2 = b.length;
int n3 = c.length;
int minVal = Integer.MAX_VALUE;
// Try all possible triplets
for (int i = 0; i < n1; i++) {
for (int j = 0; j < n2; j++) {
for (int k = 0; k < n3; k++) {
// Find maximum absolute difference
int curr = Math.max(Math.max(Math.abs(a[i] - b[j]), Math.abs(b[j] - c[k])), Math.abs(c[k] - a[i]));
// Update minimum value
minVal = Math.min(minVal, curr);
}
}
}
return minVal;
}
public static void main(String[] args) {
int[] a = {1, 4, 10};
int[] b = {2, 15, 20};
int[] c = {10, 12};
System.out.println(findClosest(a, b, c));
}
}
def findClosest(a, b, c):
n1 = len(a)
n2 = len(b)
n3 = len(c)
minVal = float('inf')
# Try all possible triplets
for i in range(n1):
for j in range(n2):
for k in range(n3):
# Find maximum absolute difference
curr = max(abs(a[i] - b[j]), abs(b[j] - c[k]), abs(c[k] - a[i]))
# Update minimum value
minVal = min(minVal, curr)
return minVal
if __name__ == '__main__':
a = [1, 4, 10]
b = [2, 15, 20]
c = [10, 12]
print(findClosest(a, b, c))
using System;
using System.Collections.Generic;
public class GfG
{
public static int findClosest(List<int> a, List<int> b, List<int> c)
{
int n1 = a.Count;
int n2 = b.Count;
int n3 = c.Count;
int minVal = int.MaxValue;
// Try all possible triplets
for (int i = 0; i < n1; i++)
{
for (int j = 0; j < n2; j++)
{
for (int k = 0; k < n3; k++)
{
// Find maximum absolute difference
int curr = Math.Max(
Math.Max(Math.Abs(a[i] - b[j]),
Math.Abs(b[j] - c[k])),
Math.Abs(c[k] - a[i]));
// Update minimum value
minVal = Math.Min(minVal, curr);
}
}
}
return minVal;
}
public static void Main()
{
List<int> a = new List<int> {1, 4, 10};
List<int> b = new List<int> {2, 15, 20};
List<int> c = new List<int> {10, 12};
Console.WriteLine(findClosest(a, b, c));
}
}
function findClosest(a, b, c) {
let n1 = a.length;
let n2 = b.length;
let n3 = c.length;
let minVal = Number.MAX_VALUE;
// Try all possible triplets
for (let i = 0; i < n1; i++) {
for (let j = 0; j < n2; j++) {
for (let k = 0; k < n3; k++) {
// Find maximum absolute difference
let curr = Math.max(Math.abs(a[i] - b[j]), Math.abs(b[j] - c[k]), Math.abs(c[k] - a[i]));
// Update minimum value
minVal = Math.min(minVal, curr);
}
}
}
return minVal;
}
let a = [1, 4, 10];
let b = [2, 15, 20];
let c = [10, 12];
console.log(findClosest(a, b, c));
Output
5
[Expected Approach] Using Three Pointers - O(n1 + n2 + n3) Time and O(1) Space
The problem can be reformulated as finding the triplet (a[i], b[j], c[k]) that minimizes the difference between the maximum and minimum elements among the three. Since the arrays are sorted, we can use a three pointer approach.
The idea is to use three pointers starting from the beginning of the three sorted arrays. At every step, the current elements form a triplet. We calculate the minimum and maximum among these three elements and try to minimize their difference. Since the arrays are sorted, the best way to reduce the range is to move the pointer pointing to the smallest element, because increasing the minimum value may help in reducing the difference in the next steps.
We continue this process as long as all three pointers remain within their arrays. During the traversal, we keep track of the smallest max - min encountered and the corresponding triplet. At the end, the triplet with the minimum difference is returned as the answer.
#include <algorithm>
#include <climits>
#include <iostream>
#include <vector>
using namespace std;
int findClosest(vector<int> &a, vector<int> &b, vector<int> &c)
{
// Sizes of the three arrays
int p = a.size();
int q = b.size();
int r = c.size();
// Stores minimum difference found so far
int diff = INT_MAX;
// Stores indices of elements giving minimum difference
int res_i = 0, res_j = 0, res_k = 0;
// Pointers for three arrays
int i = 0, j = 0, k = 0;
// Traverse all arrays together
while (i < p && j < q && k < r)
{
// Current minimum element
int minimum = min(a[i], min(b[j], c[k]));
// Current maximum element
int maximum = max(a[i], max(b[j], c[k]));
// Update answer if smaller range found
if (maximum - minimum < diff)
{
res_i = i;
res_j = j;
res_k = k;
diff = maximum - minimum;
}
// Best possible answer
if (diff == 0)
break;
// Move pointer having minimum value
if (a[i] == minimum)
i++;
else if (b[j] == minimum)
j++;
else
k++;
}
// Pairwise absolute differences
int x1 = abs(a[res_i] - b[res_j]);
int x2 = abs(c[res_k] - b[res_j]);
int x3 = abs(a[res_i] - c[res_k]);
// Return maximum among the three differences
return max(x1, max(x2, x3));
}
// Driver Code
int main()
{
vector<int> a = {1, 4, 10};
vector<int> b = {2, 15, 20};
vector<int> c = {10, 12};
cout << findClosest(a, b, c);
return 0;
}
import java.util.Arrays;
public class GfG {
// Function to find the triplet with minimum difference
static int findClosest(int[] a, int[] b, int[] c) {
// Sizes of the three arrays
int p = a.length;
int q = b.length;
int r = c.length;
// Stores minimum difference found so far
int diff = Integer.MAX_VALUE;
// Stores indices of elements giving minimum difference
int res_i = 0, res_j = 0, res_k = 0;
// Pointers for three arrays
int i = 0, j = 0, k = 0;
// Traverse all arrays together
while (i < p && j < q && k < r) {
// Current minimum element
int minimum = Math.min(a[i], Math.min(b[j], c[k]));
// Current maximum element
int maximum = Math.max(a[i], Math.max(b[j], c[k]));
// Update answer if smaller range found
if (maximum - minimum < diff) {
res_i = i;
res_j = j;
res_k = k;
diff = maximum - minimum;
}
// Best possible answer
if (diff == 0)
break;
// Move pointer having minimum value
if (a[i] == minimum)
i++;
else if (b[j] == minimum)
j++;
else
k++;
}
// Pairwise absolute differences
int x1 = Math.abs(a[res_i] - b[res_j]);
int x2 = Math.abs(c[res_k] - b[res_j]);
int x3 = Math.abs(a[res_i] - c[res_k]);
// Return maximum among the three differences
return Math.max(x1, Math.max(x2, x3));
}
public static void main(String[] args) {
int[] a = {1, 4, 10};
int[] b = {2, 15, 20};
int[] c = {10, 12};
System.out.println(findClosest(a, b, c));
}
}
def findClosest(a, b, c):
# Sizes of the three arrays
p = len(a)
q = len(b)
r = len(c)
# Stores minimum difference found so far
diff = float('inf')
# Stores indices of elements giving minimum difference
res_i = 0
res_j = 0
res_k = 0
# Pointers for three arrays
i = 0
j = 0
k = 0
# Traverse all arrays together
while i < p and j < q and k < r:
# Current minimum element
minimum = min(a[i], min(b[j], c[k]))
# Current maximum element
maximum = max(a[i], max(b[j], c[k]))
# Update answer if smaller range found
if maximum - minimum < diff:
res_i = i
res_j = j
res_k = k
diff = maximum - minimum
# Best possible answer
if diff == 0:
break
# Move pointer having minimum value
if a[i] == minimum:
i += 1
elif b[j] == minimum:
j += 1
else:
k += 1
# Pairwise absolute differences
x1 = abs(a[res_i] - b[res_j])
x2 = abs(c[res_k] - b[res_j])
x3 = abs(a[res_i] - c[res_k])
# Return maximum among the three differences
return max(x1, max(x2, x3))
if __name__ == "__main__":
a = [1, 4, 10]
b = [2, 15, 20]
c = [10, 12]
print(findClosest(a, b, c))
using System;
using System.Collections.Generic;
class GfG
{
// Function to find the triplet with minimum difference
static int findClosest(List<int> a, List<int> b, List<int> c)
{
// Sizes of the three arrays
int p = a.Count;
int q = b.Count;
int r = c.Count;
// Stores minimum difference found so far
int diff = int.MaxValue;
// Stores indices of elements giving minimum difference
int res_i = 0, res_j = 0, res_k = 0;
// Pointers for three arrays
int i = 0, j = 0, k = 0;
// Traverse all arrays together
while (i < p && j < q && k < r)
{
// Current minimum element
int minimum = Math.Min(a[i], Math.Min(b[j], c[k]));
// Current maximum element
int maximum = Math.Max(a[i], Math.Max(b[j], c[k]));
// Update answer if smaller range found
if (maximum - minimum < diff)
{
res_i = i;
res_j = j;
res_k = k;
diff = maximum - minimum;
}
// Best possible answer
if (diff == 0)
break;
// Move pointer having minimum value
if (a[i] == minimum)
i++;
else if (b[j] == minimum)
j++;
else
k++;
}
// Pairwise absolute differences
int x1 = Math.Abs(a[res_i] - b[res_j]);
int x2 = Math.Abs(c[res_k] - b[res_j]);
int x3 = Math.Abs(a[res_i] - c[res_k]);
// Return maximum among the three differences
return Math.Max(x1, Math.Max(x2, x3));
}
static void Main()
{
List<int> a = new List<int> { 1, 4, 10 };
List<int> b = new List<int> { 2, 15, 20 };
List<int> c = new List<int> { 10, 12 };
Console.WriteLine(findClosest(a, b, c));
}
}
function findClosest(a, b, c) {
// Sizes of the three arrays
let p = a.length;
let q = b.length;
let r = c.length;
// Stores minimum difference found so far
let diff = Number.MAX_SAFE_INTEGER;
// Stores indices of elements giving minimum difference
let res_i = 0, res_j = 0, res_k = 0;
// Pointers for three arrays
let i = 0, j = 0, k = 0;
// Traverse all arrays together
while (i < p && j < q && k < r) {
// Current minimum element
let minimum = Math.min(a[i], Math.min(b[j], c[k]));
// Current maximum element
let maximum = Math.max(a[i], Math.max(b[j], c[k]));
// Update answer if smaller range found
if (maximum - minimum < diff) {
res_i = i;
res_j = j;
res_k = k;
diff = maximum - minimum;
}
// Best possible answer
if (diff == 0)
break;
// Move pointer having minimum value
if (a[i] == minimum)
i++;
else if (b[j] == minimum)
j++;
else
k++;
}
// Pairwise absolute differences
let x1 = Math.abs(a[res_i] - b[res_j]);
let x2 = Math.abs(c[res_k] - b[res_j]);
let x3 = Math.abs(a[res_i] - c[res_k]);
// Return maximum among the three differences
return Math.max(x1, Math.max(x2, x3));
}
// Driver Code
let a = [1, 4, 10];
let b = [2, 15, 20];
let c = [10, 12];
console.log(findClosest(a, b, c));
Output
5