Find closest value for every element in array
Given an array of integers, find the closest element for every element.
Examples:
Input : arr[] = {10, 5, 11, 6, 20, 12}
Output : 11 6 12 5 12 11
Input : arr[] = {10, 5, 11, 10, 20, 12}
Output : 10 10 12 10 12 11
A simple solution is to run two nested loops. We pick an outer element one by one. For every picked element, we traverse the remaining array and find the closest element. The time complexity of this solution is O(N2).
Steps:
1. Create a base case in which if the size of the
‘vec’ array is one print -1;
2.create a nested iterations using the ‘for’ loop with the help of
‘i’ and ‘j’ variables.
3. Take two variables to store the abs() difference and closest
element for an element.
4. In the second ‘for’ loop, assign the value at the ‘jth’
position of the ‘vec’ vector, if that element is close to
the respective element.
5.Print the closest element.
Implementation of above approach :
C++
#include <bits/stdc++.h>
using namespace std;
void getResult(vector< int > vec, int n)
{
if (n <= 1) {
cout << "-1" << endl;
return ;
}
for ( int i = 0; i < n; i++) {
int mini = INT_MAX;
int mini_diff = INT_MAX;
for ( int j = 0; j < n; j++) {
if ((i ^ j)) {
int temp
= abs (vec[i] - vec[j]);
if (temp < mini_diff) {
mini = vec[j];
mini_diff = temp;
}
}
}
cout << mini << " " ;
}
return ;
}
int main()
{
vector< int > vec = { 10, 5, 11, 6, 20, 12, 10};
int n = vec.size();
cout << "vec Array:- " ;
for ( int i = 0; i < n; i++) {
cout << vec[i] << " " ;
}
cout << endl;
cout << "Resultant Array:- " ;
getResult(vec, n);
}
|
Python3
import sys
def get_result(arr, n):
if n < = 1 :
print ( "-1" )
return
for i in range (n):
mini = sys.maxsize
mini_diff = sys.maxsize
for j in range (n):
if i ! = j:
temp = abs (arr[i] - arr[j])
if temp < mini_diff:
mini = arr[j]
mini_diff = temp
print (mini, end = " " )
return
if __name__ = = "__main__" :
arr = [ 10 , 5 , 11 , 6 , 20 , 12 , 10 ]
n = len (arr)
print ( "vec Array:-" , end = " " )
for i in range (n):
print (arr[i], end = " " )
print ()
print ( "Resultant Array:-" , end = " " )
get_result(arr, n)
|
Java
import java.util.*;
public class Main {
public static void getResult(List<Integer> vec, int n)
{
if (n <= 1 ) {
System.out.println( "-1" );
return ;
}
for ( int i = 0 ; i < n; i++) {
int mini = Integer.MAX_VALUE;
int mini_diff = Integer.MAX_VALUE;
for ( int j = 0 ; j < n; j++) {
if ((i ^ j) != 0 ) {
int temp
= Math.abs(vec.get(i) - vec.get(j));
if (temp < mini_diff) {
mini = vec.get(j);
mini_diff = temp;
}
}
}
System.out.print(mini + " " );
}
}
public static void main(String[] args)
{
List<Integer> vec
= Arrays.asList( 10 , 5 , 11 , 6 , 20 , 12 , 10 );
int n = vec.size();
System.out.print( "vec Array:- " );
for ( int i = 0 ; i < n; i++) {
System.out.print(vec.get(i) + " " );
}
System.out.println( "\nResultant Array:- " );
getResult(vec, n);
}
}
|
C#
using System;
using System.Collections.Generic;
public class Program
{
public static void Main()
{
List< int > vec = new List< int >{ 10, 5, 11, 6, 20, 12, 10 };
int n = vec.Count;
Console.Write( "vec Array:- " );
for ( int i = 0; i < n; i++) {
Console.Write(vec[i] + " " );
}
Console.WriteLine();
Console.Write( "Resultant Array:- " );
GetResult(vec, n);
}
static void GetResult(List< int > vec, int n)
{
if (n <= 1) {
Console.WriteLine( "-1" );
return ;
}
for ( int i = 0; i < n; i++) {
int mini = int .MaxValue;
int mini_diff = int .MaxValue;
for ( int j = 0; j < n; j++) {
if ((i ^ j) != 0) {
int temp = Math.Abs(vec[i] - vec[j]);
if (temp < mini_diff) {
mini = vec[j];
mini_diff = temp;
}
}
}
Console.Write(mini + " " );
}
}
}
|
Javascript
function getResult(vec) {
const n = vec.length;
if (n <= 1) {
console.log( "-1" );
return ;
}
for (let i = 0; i < n; i++) {
let mini = Number.MAX_SAFE_INTEGER;
let mini_diff = Number.MAX_SAFE_INTEGER;
for (let j = 0; j < n; j++) {
if (i !== j) {
const temp = Math.abs(vec[i] - vec[j]);
if (temp < mini_diff) {
mini = vec[j];
mini_diff = temp;
}
}
}
process.stdout.write(mini + " " );
}
console.log( "" );
}
const vec = [10, 5, 11, 6, 20, 12, 10];
console.log( "vec Array:- " + vec.join( " " ));
console.log( "Resultant Array:- " );
getResult(vec);
|
Output
vec Array:- 10 5 11 6 20 12 10
Resultant Array:- 10 6 10 5 12 11 10
Time Complexity: O(N2)
Auxiliary Space: O(1)
An efficient solution is to use Self Balancing BST (Implemented as set in C++ and TreeSet in Java). In a Self Balancing BST, we can do both insert and closest greater operations in O(Log n) time.
Implementation:
C++
#include <iostream>
#include <set>
#include <map>
using namespace std;
void closestGreater( int arr[], int n)
{
if (n == -1) {
cout << -1 << " " ;
return ;
}
map< int , bool > mp;
for ( int i = 0; i < n; i++) {
if (mp.find(arr[i]) != mp.end())
mp[arr[i]] = true ;
else
mp[arr[i]] = false ;
}
for ( int i = 0; i < n; i++) {
if (mp[arr[i]] == true )
{
cout << arr[i] << " " ;
continue ;
}
int greater = 0, lower = 0;
auto it = mp.upper_bound(arr[i]);
if (it != mp.end())
greater = it->first;
it = mp.lower_bound(arr[i]);
if (it != mp.begin()) {
--it;
lower = it->first;
}
if (greater == 0)
cout << lower << " " ;
else if (lower == 0)
cout << greater << " " ;
else {
int d1 = greater - arr[i];
int d2 = arr[i] - lower;
if (d1 > d2)
cout << lower << " " ;
else
cout << greater << " " ;
}
}
}
int main()
{
int arr[] = { 10, 5, 11, 6, 20, 12, 10 };
int n = sizeof (arr) / sizeof (arr[0]);
closestGreater(arr, n);
return 0;
}
|
Java
import java.util.*;
class TreeSetDemo {
public static void closestGreater( int [] arr)
{
if (arr.length == - 1 ) {
System.out.print(- 1 + " " );
return ;
}
TreeMap<Integer, Boolean> tm =
new TreeMap<Integer, Boolean>();
for ( int i = 0 ; i < arr.length; i++) {
if (tm.containsKey(arr[i]))
tm.put(arr[i], true );
else
tm.put(arr[i], false );
}
for ( int i = 0 ; i < arr.length; i++) {
if (tm.get(arr[i]) == true )
{
System.out.print(arr[i] + " " );
continue ;
}
Integer greater = tm.higherKey(arr[i]);
Integer lower = tm.lowerKey(arr[i]);
if (greater == null )
System.out.print(lower + " " );
else if (lower == null )
System.out.print(greater + " " );
else {
int d1 = greater - arr[i];
int d2 = arr[i] - lower;
if (d1 > d2)
System.out.print(lower + " " );
else
System.out.print(greater + " " );
}
}
}
public static void main(String[] args)
{
int [] arr = { 10 , 5 , 11 , 6 , 20 , 12 , 10 };
closestGreater(arr);
}
}
|
Python3
from collections import defaultdict
def closest_greater(arr):
if len (arr) = = 0 :
print ( "-1" , end = " " )
return
d = defaultdict( int )
for i in range ( len (arr)):
d[arr[i]] + = 1
for i in range ( len (arr)):
if d[arr[i]] > 1 :
print (arr[i], end = " " )
continue
greater = None
lower = None
for key in sorted (d.keys()):
if key > arr[i]:
greater = key
break
elif key < arr[i]:
lower = key
if greater is None :
print (lower, end = " " )
elif lower is None :
print (greater, end = " " )
else :
d1 = greater - arr[i]
d2 = arr[i] - lower
if d1 > d2:
print (lower, end = " " )
else :
print (greater, end = " " )
if __name__ = = "__main__" :
arr = [ 10 , 5 , 11 , 6 , 20 , 12 , 10 ]
closest_greater(arr)
|
C#
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static void Main( string [] args)
{
int [] arr = { 10, 5, 11, 6, 20, 12, 10 };
ClosestGreater(arr);
}
static void ClosestGreater( int [] arr)
{
if (arr.Length == 0)
{
Console.Write( "-1 " );
return ;
}
var dict = new Dictionary< int , int >();
foreach ( int num in arr)
{
if (dict.ContainsKey(num))
{
dict[num]++;
}
else
{
dict[num] = 1;
}
}
foreach ( int num in arr)
{
if (dict[num] > 1)
{
Console.Write(num + " " );
continue ;
}
int ? greater = null ;
int ? lower = null ;
foreach ( int key in dict.Keys.OrderBy(x => x))
{
if (key > num)
{
greater = key;
break ;
}
else if (key < num)
{
lower = key;
}
}
if (greater == null )
{
Console.Write(lower + " " );
}
else if (lower == null )
{
Console.Write(greater + " " );
}
else
{
int d1 = greater.Value - num;
int d2 = num - lower.Value;
if (d1 > d2)
{
Console.Write(lower + " " );
}
else
{
Console.Write(greater + " " );
}
}
}
}
}
|
Javascript
function closestGreater(arr) {
if (arr.length === 0) {
console.log(-1 + " " );
return ;
}
let map = new Map();
for (let i = 0; i < arr.length; i++) {
if (map.has(arr[i]))
map.set(arr[i], true );
else
map.set(arr[i], false );
}
for (let i = 0; i < arr.length; i++) {
if (map.get(arr[i]) === true ) {
console.log(arr[i] + " " );
continue ;
}
let greater = null , lower = null ;
for (let [key, value] of map) {
if (key > arr[i]) {
if (!greater || key < greater)
greater = key;
} else if (key < arr[i]) {
if (!lower || key > lower)
lower = key;
}
}
if (greater === null )
console.log(lower + " " );
else if (lower === null )
console.log(greater + " " );
else {
let d1 = greater - arr[i];
let d2 = arr[i] - lower;
if (d1 > d2)
console.log(lower + " " );
else
console.log(greater + " " );
}
}
}
let arr = [10, 5, 11, 6, 20, 12, 10];
closestGreater(arr);
|
Output:
10 6 12 5 12 11 10
Time Complexity:
- The first loop for inserting all the elements into the TreeMap takes O(nlog(n)) time because TreeMap uses a Red-Black tree internally to store the elements, and insertion takes O(log(n)) time in the average case, and since there are ‘n’ elements in the array, the total time complexity for inserting all elements into the TreeMap is O(nlog(n)).
- The second loop for finding the smallest greater element for each array element takes O(nlog(n)) time because the TreeMap provides the higherKey() and lowerKey() methods that take O(log(n)) time in the average case to find the keys greater than and less than the given key, respectively. Since we are calling these methods ‘n’ times, the total time complexity for finding the smallest greater element for each array element is O(nlog(n)).
Therefore, the overall time complexity of the algorithm is O(n*log(n)).
Auxiliary Space:
- The algorithm uses a TreeMap to store the array elements, which takes O(n) space because each element takes O(1) space, and there are ‘n’ elements in the array.
- Therefore, the overall auxiliary space complexity of the algorithm is O(n).
Exercise: Another efficient solution is to use sorting that also works in O(n Log n) time. Write complete algorithm and code for sorting based solution.
Last Updated :
28 Mar, 2023
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...