Find closest smaller value for every element in array
Given an array of integers, find the closest smaller element for every element. If there is no smaller element then print -1
Examples:
Input : arr[] = {10, 5, 11, 6, 20, 12}
Output : 6, -1, 10, 5, 12, 11
Input : arr[] = {10, 5, 11, 10, 20, 12}
Output : 5 -1 10 5 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 remaining array and find closest smaller element. Time complexity of this solution is O(n*n)
A better solution is to use sorting. We sort all elements, then for every element, traverse toward left until we find a smaller element (Note that there can be multiple occurrences of an element).
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 smaller operations in O(Log n) time.
Implementation:
C++
#include <bits/stdc++.h>
using namespace std;
void closestSmaller( int arr[], int n)
{
set< int > ts;
for ( int i = 0; i < n; i++)
ts.insert(arr[i]);
for ( int i = 0; i < n; i++)
{
auto smaller = ts.lower_bound(arr[i]);
if (smaller == ts.begin())
cout << -1 << " " ;
else
cout << *(--smaller) << " " ;
}
}
int main()
{
int arr[] = {10, 5, 11, 6, 20, 12};
int n = sizeof (arr) / sizeof (arr[0]);
closestSmaller(arr, n);
return 0;
}
|
Java
import java.util.*;
class TreeSetDemo {
public static void closestSmaller( int [] arr)
{
TreeSet<Integer> ts = new TreeSet<Integer>();
for ( int i = 0 ; i < arr.length; i++)
ts.add(arr[i]);
for ( int i = 0 ; i < arr.length; i++) {
Integer smaller = ts.lower(arr[i]);
if (smaller == null )
System.out.print(- 1 + " " );
else
System.out.print(smaller + " " );
}
}
public static void main(String[] args)
{
int [] arr = { 10 , 5 , 11 , 6 , 20 , 12 };
closestSmaller(arr);
}
}
|
Python3
import bisect
def closestSmaller(arr, n):
ts = set ()
for i in range (n):
ts.add(arr[i])
for i in range (n):
smaller = bisect.bisect_left( list (ts), arr[i])
if (smaller = = 0 ):
print ( - 1 , end = " " )
else :
print (( list (ts)[smaller - 1 ]), end = " " )
smaller - = 1
arr = [ 10 , 5 , 11 , 6 , 20 , 12 ]
n = len (arr)
closestSmaller(arr, n)
|
C#
using System;
using System.Linq;
using System.Collections.Generic;
public class TreeSetDemo {
public static void closestSmaller( int [] arr)
{
SortedSet< int > ts = new SortedSet< int >();
for ( int i = 0; i < arr.Length; i++)
ts.Add(arr[i]);
for ( int i = 0; i < arr.Length; i++) {
int smaller = lower_bound(ts, arr[i]);
if (smaller == 0)
Console.Write(-1 + " " );
else
Console.Write(smaller + " " );
}
}
public static int lower_bound(SortedSet< int > s, int val)
{
List< int > temp = new List< int >();
temp.AddRange(s);
temp.Sort();
temp.Reverse();
if (temp.IndexOf(val) + 1 == temp.Count)
return -1;
return temp[temp.IndexOf(val) + 1];
}
public static void Main(String[] args)
{
int [] arr = { 10, 5, 11, 6, 20, 12 };
closestSmaller(arr);
}
}
|
Javascript
<script>
function closestSmaller(arr)
{
var ts = new Set();
for (i = 0; i < arr.length; i++)
ts.add(arr[i]);
for (i = 0; i < arr.length; i++) {
var smaller = upper_bound(ts, arr[i]);
if (smaller == null )
document.write(-1 + " " );
else
document.write(smaller + " " );
}
}
function upper_bound(s, val)
{
let temp = [...s];
temp.sort((a, b) => b - a);
return temp[temp.indexOf(val) + 1];
}
var arr = [ 10, 5, 11, 6, 20, 12 ];
closestSmaller(arr);
</script>
|
Complexity Analysis:P
- Time Complexity: O(n Log n)
- Auxiliary Space: O(n) because using space for set
Last Updated :
09 Sep, 2022
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...