Find the nearest value present on the left of every array element
Last Updated :
11 Mar, 2024
Given an array arr[] of size N, the task is for each array element is to find the nearest non-equal value present on its left in the array. If no such element is found, then print -1
Examples:
Input: arr[] = { 2, 1, 5, 8, 3 }
Output: -1 2 2 5 2
Explanation:
[2], it is the only number in this prefix. Hence, answer is -1.
[2, 1], the closest number to 1 is 2
[2, 1, 5], the closest number to 5 is 2
[2, 1, 5, 8], the closest number to 8 is 5
[2, 1, 5, 8, 3], the closest number to 3 is 2
Input: arr[] = {3, 3, 2, 4, 6, 5, 5, 1}
Output: -1 -1 3 3 4 4 4 2
Explanation:
[3], it is the only number in this prefix. Hence, answer is -1.
[3, 3], it is the only number in this prefix. Hence, answer is -1
[3, 3, 2], the closest number to 2 is 3
[3, 3, 2, 4], the closest number to 4 is 3
[3, 3, 2, 4, 6], the closest number to 6 is 4
[3, 3, 2, 4, 6, 5], the closest number to 5 is 4
[3, 3, 2, 4, 6, 5, 5], the closest number to 5 is 4
[3, 3, 2, 4, 6, 5, 5, 1], the closest number to 1 is 2
Naive Approach: The simplest idea is to traverse the given array and for every ith element, find the closest element on the left side of index i which is not equal to arr[i].
Time Complexity: O(N^2)
Auxiliary Space: O(1)
Efficient Approach:
The idea is to insert the elements of the given array in a Set such that the inserted numbers are sorted and then for an integer, find its position and compare its next value with the previous value, and print the closer value out of the two.
Follow the steps below to solve the problem:
- Initialize a Set of integers S to store the elements in sorted order.
- Traverse the array arr[] using the variable i.
- Now, find the nearest value smaller as well as greater than arr[i], say X and Y respectively.
- If X cannot be found, print Y.
- If Y cannot be found, print Z.
- If both X and Y cannot be found, print “-1”.
- After that, add arr[i] to the Set S and print X if abs(X – arr[i]) is smaller than abs(Y – arr[i]). Otherwise, print Y.
- Repeat the above steps for every element.
Below is the implementation of the above approach:
C++14
#include <bits/stdc++.h>
using namespace std;
void printClosest(set< int >& streamNumbers, int x)
{
auto it = streamNumbers.insert(x).first;
if (it == streamNumbers.begin())
{
if (next(it) == streamNumbers.end())
{
cout << "-1 " ;
return ;
}
int rightVal = *next(it);
cout << rightVal << " " ;
return ;
}
int leftVal = *prev(it);
if (next(it) == streamNumbers.end()) {
cout << leftVal << " " ;
return ;
}
int rightVal = *next(it);
if (x - leftVal <= rightVal - x)
cout << leftVal << " " ;
else
cout << rightVal << " " ;
}
int main()
{
vector< int > arr = { 3, 3, 2, 4, 6, 5, 5, 1 };
set< int > streamNumbers;
for ( int i = 0; i < arr.size(); i++) {
printClosest(streamNumbers, arr[i]);
}
return 0;
}
|
Java
import java.util.*;
class Main {
static void printClosest(SortedSet<Integer> streamNumbers, int x) {
streamNumbers.add(x);
int rightVal, leftVal;
List<Integer> it = new ArrayList<>(streamNumbers);
it.sort( null );
int i = it.indexOf(x);
if (it.get(i) == it.get( 0 )) {
if (it.size() == 1 ) {
System.out.print( "-1 " );
return ;
}
rightVal = it.get(i + 1 );
System.out.print(rightVal + " " );
return ;
}
leftVal = it.get(i - 1 );
if (i + 1 == it.size()) {
System.out.print(leftVal + " " );
return ;
}
rightVal = it.get(i + 1 );
if (x - leftVal <= rightVal - x)
System.out.print(leftVal + " " );
else
System.out.print(rightVal + " " );
}
public static void main(String[] args) {
int [] arr = { 3 , 3 , 2 , 4 , 6 , 5 , 5 , 1 };
SortedSet<Integer> streamNumbers = new TreeSet<>();
for ( int i = 0 ; i < arr.length; i++) {
printClosest(streamNumbers, arr[i]);
}
}
}
|
Python3
def printClosest(streamNumbers, x):
streamNumbers.add(x);
it = sorted (streamNumbers)
i = it.index(x);
if (it[i] = = it[ 0 ]):
if ( len (it) = = 1 ):
print ( "-1" , end = " " );
return ;
rightVal = it[i + 1 ]
print (rightVal, end = " " );
return ;
leftVal = it[i - 1 ]
if (i + 1 = = len (it) ):
print (leftVal, end = " " );
return ;
rightVal = it[i + 1 ];
if (x - leftVal < = rightVal - x):
print (leftVal, end = " " );
else :
print (rightVal, end = " " );
arr = [ 3 , 3 , 2 , 4 , 6 , 5 , 5 , 1 ];
streamNumbers = set ()
for i in range ( len (arr)):
printClosest(streamNumbers, arr[i]);
|
C#
using System;
using System.Linq;
using System.Collections.Generic;
class GFG
{
static void printClosest(SortedSet< int > streamNumbers, int x)
{
streamNumbers.Add(x);
int rightVal, leftVal;
var it = streamNumbers.ToList();
it.Sort();
var i = it.IndexOf(x);
if (it[i] == it[0])
{
if ( it.Count == 1)
{
Console.Write( "-1 " );
return ;
}
rightVal = it[i + 1];
Console.Write(rightVal + " " );
return ;
}
leftVal = it[i - 1];
if (i + 1 == it.Count ) {
Console.Write(leftVal + " " );
return ;
}
rightVal = it[i + 1];
if (x - leftVal <= rightVal - x)
Console.Write(leftVal + " " );
else
Console.Write(rightVal + " " );
}
public static void Main( string [] args)
{
int [] arr = { 3, 3, 2, 4, 6, 5, 5, 1 };
var streamNumbers = new SortedSet< int >();
for ( var i = 0; i < arr.Length; i++)
{
printClosest(streamNumbers, arr[i]);
}
}
}
|
Javascript
function printClosest(streamNumbers, x)
{
streamNumbers.add(x);
let it = Array.from(streamNumbers)
it.sort( function (a, b) { return a - b})
let i = it.indexOf(x);
if (it[i] == it[0])
{
if ( it.length == 1)
{
process.stdout.write( "-1 " );
return ;
}
let rightVal = it[i + 1]
process.stdout.write(rightVal + " " );
return ;
}
let leftVal = it[i - 1]
if (i + 1 == it.length ) {
process.stdout.write(leftVal + " " );
return ;
}
let rightVal = it[i + 1];
if (x - leftVal <= rightVal - x)
process.stdout.write(leftVal + " " );
else
process.stdout.write(rightVal + " " );
}
let arr = [ 3, 3, 2, 4, 6, 5, 5, 1 ];
let streamNumbers = new Set();
for ( var i = 0; i < arr.length; i++) {
printClosest(streamNumbers, arr[i]);
}
|
Time Complexity: O(N * log(N))
Auxiliary Space: O(N)
Share your thoughts in the comments
Please Login to comment...