Given three integer arrays a[], b[] and c[] of equal size n, find a triplet (one element from each array) that minimizes the difference between its maximum and minimum elements.
If there is a tie, return the triplet with the smallest sum. The final triplet must be returned in descending order.
Examples :
Input : a[] = [5, 2, 8], b[] = [10, 7, 12], c[] = [9, 14, 6]
Output : [7, 6, 5]
Explanation: The triplet (7, 6, 5) gives the minimum possible difference between the maximum and minimum values, so it is selected.
Input : a[] = [5, 12, 18, 9], b[] = [10, 17, 13, 8], c[] = [14, 16, 11, 5]
Output : [11, 10, 9]
Explanation: Multiple triplets have the same minimum difference, and among them (11, 10, 9) has the smallest sum, so it is chosen.
Table of Content
[Naive Approach] Try Every Possible Triplet - O(n^3) Time and O(1) Space
We consider each and every triplet using three nested loops and compute the difference between the maximum and minimum values in each triplet.
We mainly run three nested loops to find all triplets. Among all triplets, we select the one that gives the smallest difference, updating the answer whenever a better triplet is found.
#include <iostream>
#include <vector>
#include <algorithm>
#include <climits>
using namespace std;
vector<int> smallestDiff(vector<int> &a, vector<int> &b, vector<int> &c) {
int n = a.size();
vector<int> res(3);
int minDiff = INT_MAX, minSum = INT_MAX;
// Iterate over all possible triplets
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
for (int k = 0; k < n; k++) {
int mx = max({a[i], b[j], c[k]});
int mn = min({a[i], b[j], c[k]});
int diff = mx - mn;
int sum = a[i] + b[j] + c[k];
// Update result if a better triplet is found
if (diff < minDiff || (diff == minDiff && sum < minSum)) {
minDiff = diff;
minSum = sum;
res = {a[i], b[j], c[k]};
}
}
}
}
// reverse sorted order
sort(res.rbegin(), res.rend());
return res;
}
int main() {
vector<int> arr1 = {5, 2, 8};
vector<int> arr2 = {10, 7, 12};
vector<int> arr3 = {9, 14, 6};
vector<int> res = smallestDiff(arr1, arr2, arr3);
cout << res[0] << " " << res[1] << " " << res[2] << endl;
return 0;
}
import java.util.Arrays;
import java.util.ArrayList;
import java.util.Collections;
public class GFG {
public static ArrayList<Integer> smallestDiff(int[] a, int[] b, int[] c) {
int n = a.length;
// Variables to store the best triplet temporarily
int r1 = 0, r2 = 0, r3 = 0;
int minDiff = Integer.MAX_VALUE, minSum = Integer.MAX_VALUE;
// Iterate over all possible triplets
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
for (int k = 0; k < n; k++) {
int mx = Math.max(Math.max(a[i], b[j]), c[k]);
int mn = Math.min(Math.min(a[i], b[j]), c[k]);
int diff = mx - mn;
int sum = a[i] + b[j] + c[k];
// Update result if a better triplet is found
if (diff < minDiff || (diff == minDiff && sum < minSum)) {
minDiff = diff;
minSum = sum;
r1 = a[i];
r2 = b[j];
r3 = c[k];
}
}
}
}
// Add the best triplet to an ArrayList
ArrayList<Integer> res = new ArrayList<>();
res.add(r1);
res.add(r2);
res.add(r3);
// Sort the ArrayList in reverse (descending) order
Collections.sort(res, Collections.reverseOrder());
return res;
}
public static void main(String[] args) {
int[] arr1 = {5, 2, 8};
int[] arr2 = {10, 7, 12};
int[] arr3 = {9, 14, 6};
ArrayList<Integer> res = smallestDiff(arr1, arr2, arr3);
System.out.println(res.get(0) + " " + res.get(1) + " " + res.get(2));
}
}
def smallestDiff(a, b, c):
n = len(a)
res = [0, 0, 0]
minDiff = float('inf')
minSum = float('inf')
# Iterate over all possible triplets
for i in range(n):
for j in range(n):
for k in range(n):
mx = max(a[i], b[j], c[k])
mn = min(a[i], b[j], c[k])
diff = mx - mn
s = a[i] + b[j] + c[k]
# Update result if a better triplet is found
if diff < minDiff or (diff == minDiff and s < minSum):
minDiff = diff
minSum = s
res = [a[i], b[j], c[k]]
# reverse sorted order
res.sort(reverse=True)
return res
if __name__ == "__main__":
arr1 = [5, 2, 8]
arr2 = [10, 7, 12]
arr3 = [9, 14, 6]
res = smallestDiff(arr1, arr2, arr3)
print(res[0], res[1], res[2])
using System;
using System.Collections.Generic;
using System.Linq;
public class GFG {
public static List<int> smallestDiff(int[] a, int[] b, int[] c) {
int n = a.Length;
// Variables to store the best triplet temporarily
int r1 = 0, r2 = 0, r3 = 0;
int minDiff = int.MaxValue, minSum = int.MaxValue;
// Iterate over all possible triplets
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
for (int k = 0; k < n; k++) {
int mx = Math.Max(Math.Max(a[i], b[j]), c[k]);
int mn = Math.Min(Math.Min(a[i], b[j]), c[k]);
int diff = mx - mn;
int sum = a[i] + b[j] + c[k];
// Update result if a better triplet is found
if (diff < minDiff || (diff == minDiff && sum < minSum)) {
minDiff = diff;
minSum = sum;
r1 = a[i];
r2 = b[j];
r3 = c[k];
}
}
}
}
// Add the best triplet to a List
List<int> res = new List<int>();
res.Add(r1);
res.Add(r2);
res.Add(r3);
// Sort the List in reverse (descending) order
res.Sort();
res.Reverse();
return res;
}
public static void Main(string[] args) {
int[] arr1 = {5, 2, 8};
int[] arr2 = {10, 7, 12};
int[] arr3 = {9, 14, 6};
List<int> res = smallestDiff(arr1, arr2, arr3);
Console.WriteLine(res[0] + " " + res[1] + " " + res[2]);
}
}
function smallestDiff(a, b, c) {
let n = a.length;
let res = [0, 0, 0];
let minDiff = Infinity, minSum = Infinity;
// Iterate over all possible triplets
for (let i = 0; i < n; i++) {
for (let j = 0; j < n; j++) {
for (let k = 0; k < n; k++) {
let mx = Math.max(a[i], b[j], c[k]);
let mn = Math.min(a[i], b[j], c[k]);
let diff = mx - mn;
let sum = a[i] + b[j] + c[k];
// Update result if a better triplet is found
if (diff < minDiff || (diff === minDiff && sum < minSum)) {
minDiff = diff;
minSum = sum;
res = [a[i], b[j], c[k]];
}
}
}
}
// reverse sorted order
res.sort((x, y) => y - x);
return res;
}
//Driver Code
let arr1 = [5, 2, 8];
let arr2 = [10, 7, 12];
let arr3 = [9, 14, 6];
let res = smallestDiff(arr1, arr2, arr3);
console.log(res[0] + " " + res[1] + " " + res[2]);
Output
7 6 5
[Expected Approach] Sorting and Three Pointer - O(n*logn) Time and O(1) Space
We first sort three arrays. After sorting, use three pointers to compare.
We always move pointer of the minimum element because advancing any other pointer would keep the minimum unchanged while the maximum may increase..
Steps
- Sort all three arrays in ascending order.
- Start three pointers (i, j, k) at index 0 and set diff to infinity.
- Identify the maximum (hi) and minimum (lo) among the three current elements.
- If hi - lo < diff, update diff and save these three numbers as your best answer.
- Increment the pointer that is pointing to the lo value (to try and shrink the gap in the next step).
- Once any array is fully traversed, return the saved numbers.
Let's understand with an example:
Consider : a[] = [5, 2, 8], b[] = [10, 7, 12], c[] = [9, 14, 6]
- Set i = 0, j = 0, k = 0 and dif = INT_MAX.
- i=0, j=0, k=0: a[0]=2, b[0]=7, c[0]=6 -> lo=2, hi=7 -> hi-lo=5 < INT_MAX, so update diff=5, x=7, y=6, z=2 and lo is from a, so i++.
- i=1, j=0, k=0: a[1]=5, b[0]=7, c[0]=6 -> lo=5, hi=7 -> hi-lo=2 < 5, so update diff=2, x=7, y=6, z=5 and lo is from a, so i++.
- i=2, j=0, k=0: a[2]=8, b[0]=7, c[0]=6 -> lo=6, hi=8 -> hi-lo=2 (not < 2), no update ans lo is from c, so k++.
- i=2, j=0, k=1: a[2]=8, b[0]=7, c[1]=9 -> lo=7, hi=9 -> hi-lo=2 (not < 2), no update and lo is from b, so j++.
- i=2, j=1, k=1: a[2]=8, b[1]=10, c[1]=9 -> lo=8, hi=10 -> hi-lo=2 (not < 2), no update and lo is from a, so i++.
Loop Terminates: i becomes 3, which fails the i < a.size() condition.
Final Return: [7, 6, 5].
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
vector<int> smallestDiff(vector<int> &a, vector<int> &b, vector<int> &c)
{
// Sort three arrays
sort(a.begin(), a.end());
sort(b.begin(), b.end());
sort(c.begin(), c.end());
// Traverse three arrays from beginning
int i = 0, j = 0, k = 0, diff = INT_MAX;
// Store result
int x, y, z;
while (i < a.size() && j < b.size() && k < c.size())
{
int lo = min({a[i], b[j], c[k]});
int hi = max({a[i], b[j], c[k]});
if (diff > hi - lo)
{
diff = hi - lo;
x = hi, y = a[i] + b[j] + c[k] - (hi + lo), z = lo;
}
if (a[i] == lo)
i++;
else if (b[j] == lo)
j++;
else
k++;
}
return {x, y, z};
}
int main()
{
vector<int> a = {5, 2, 8};
vector<int> b = {10, 7, 12};
vector<int> c = {9, 14, 6};
vector<int> res = smallestDiff(a, b, c);
cout << res[0] << " " << res[1] << " " << res[2];
return 0;
}
import java.util.ArrayList;
import java.util.Arrays;
class GFG {
public static ArrayList<Integer>
smallestDiff(int[] a, int[] b, int[] c)
{
// Sort three arrays
Arrays.sort(a);
Arrays.sort(b);
Arrays.sort(c);
// Traverse three arrays from beginning
int i = 0, j = 0, k = 0, diff = Integer.MAX_VALUE;
// Store result temporarily
int x = 0, y = 0, z = 0;
while (i < a.length && j < b.length
&& k < c.length) {
int lo = Math.min(Math.min(a[i], b[j]), c[k]);
int hi = Math.max(Math.max(a[i], b[j]), c[k]);
// If a smaller difference is found, update the
// values
if (diff > hi - lo) {
diff = hi - lo;
x = hi;
y = a[i] + b[j] + c[k] - (hi + lo);
z = lo;
}
// Move the pointer of the array that contains
// the minimum value
if (a[i] == lo)
i++;
else if (b[j] == lo)
j++;
else
k++;
}
// Create the ArrayList and add the values (already
// in descending order)
ArrayList<Integer> res = new ArrayList<>();
res.add(x);
res.add(y);
res.add(z);
return res;
}
public static void main(String[] args)
{
int[] a = { 5, 2, 8 };
int[] b = { 10, 7, 12 };
int[] c = { 9, 14, 6 };
ArrayList<Integer> res = smallestDiff(a, b, c);
// Print the ArrayList values
System.out.println(res.get(0) + " " + res.get(1)
+ " " + res.get(2));
}
}
def smallestDiff(a, b, c):
# Sort three arrays
a.sort()
b.sort()
c.sort()
# Traverse three arrays from beginning
i = j = k = 0
diff = float('inf')
# Store result
x = y = z = 0
while i < len(a) and j < len(b) and k < len(c):
lo = min(a[i], b[j], c[k])
hi = max(a[i], b[j], c[k])
if diff > hi - lo:
diff = hi - lo
x = hi
y = a[i] + b[j] + c[k] - (hi + lo)
z = lo
if a[i] == lo:
i += 1
elif b[j] == lo:
j += 1
else:
k += 1
return [x, y, z]
if __name__ == '__main__':
a = [5, 2, 8]
b = [10, 7, 12]
c = [9, 14, 6]
res = smallestDiff(a, b, c)
print(res[0], res[1], res[2])
using System;
using System.Collections.Generic;
using System.Linq;
class GFG {
public static List<int> smallestDiff(int[] a, int[] b,
int[] c)
{
// Sort three arrays
Array.Sort(a);
Array.Sort(b);
Array.Sort(c);
// Traverse three arrays from beginning
int i = 0, j = 0, k = 0, diff = int.MaxValue;
// Store result temporarily
int x = 0, y = 0, z = 0;
while (i < a.Length && j < b.Length
&& k < c.Length) {
int lo = Math.Min(Math.Min(a[i], b[j]), c[k]);
int hi = Math.Max(Math.Max(a[i], b[j]), c[k]);
// If a smaller difference is found, update the
// values
if (diff > hi - lo) {
diff = hi - lo;
x = hi;
y = a[i] + b[j] + c[k] - (hi + lo);
z = lo;
}
// Move the pointer of the array that contains
// the minimum value
if (a[i] == lo)
i++;
else if (b[j] == lo)
j++;
else
k++;
}
// Create the List and add the values (already in
// descending order)
List<int> res = new List<int>();
res.Add(x);
res.Add(y);
res.Add(z);
return res;
}
public static void Main(string[] args)
{
int[] a = { 5, 2, 8 };
int[] b = { 10, 7, 12 };
int[] c = { 9, 14, 6 };
List<int> res = smallestDiff(a, b, c);
// Print the List values
Console.WriteLine(res[0] + " " + res[1] + " "
+ res[2]);
}
}
function smallestDiff(a, b, c)
{
// Sort three arrays
a.sort((x, y) => x - y);
b.sort((x, y) => x - y);
c.sort((x, y) => x - y);
// Traverse three arrays from beginning
let i = 0, j = 0, k = 0, diff = Infinity;
// Store result
let x, y, z;
while (i < a.length && j < b.length && k < c.length) {
let lo = Math.min(a[i], b[j], c[k]);
let hi = Math.max(a[i], b[j], c[k]);
if (diff > hi - lo) {
diff = hi - lo;
x = hi;
y = a[i] + b[j] + c[k] - (hi + lo);
z = lo;
}
if (a[i] === lo)
i++;
else if (b[j] === lo)
j++;
else
k++;
}
return [ x, y, z ];
}
// Driver code
let a = [5, 2, 8];
let b = [10, 7, 12];
let c = [9, 14, 6];
let res = smallestDiff(a, b, c);
console.log(res[0] + " " + res[1] + " " + res[2]);
Output
7 6 5