Find the nearest smaller numbers on left side in an array
Last Updated :
24 Jul, 2022
Given an array of integers, find the nearest smaller number for every element such that the smaller element is on the left side.
Examples:
Input: arr[] = {1, 6, 4, 10, 2, 5}
Output: {_, 1, 1, 4, 1, 2}
First element ('1') has no element on left side. For 6,
there is only one smaller element on left side '1'.
For 10, there are three smaller elements on left side (1,
6 and 4), nearest among the three elements is 4.
Input: arr[] = {1, 3, 0, 2, 5}
Output: {_, 1, _, 0, 2}
Expected time complexity is O(n).
A Simple Solution is to use two nested loops. The outer loop starts from the second element, the inner loop goes to all elements on the left side of the element picked by the outer loop and stops as soon as it finds a smaller element.
C++
#include <iostream>
using namespace std;
void printPrevSmaller( int arr[], int n)
{
cout << "_, " ;
for ( int i = 1; i < n; i++) {
int j;
for (j = i - 1; j >= 0; j--) {
if (arr[j] < arr[i]) {
cout << arr[j] << ", " ;
break ;
}
}
if (j == -1)
cout << "_, " ;
}
}
int main()
{
int arr[] = { 1, 3, 0, 2, 5 };
int n = sizeof (arr) / sizeof (arr[0]);
printPrevSmaller(arr, n);
return 0;
}
|
C
#include <stdio.h>
void printPrevSmaller( int arr[], int n)
{
printf ( "_, " );
for ( int i = 1; i < n; i++) {
int j;
for (j = i - 1; j >= 0; j--) {
if (arr[j] < arr[i]) {
printf ( "%d, " ,arr[j]);
break ;
}
}
if (j == -1)
printf ( "_, " );
}
}
int main()
{
int arr[] = { 1, 3, 0, 2, 5 };
int n = sizeof (arr) / sizeof (arr[0]);
printPrevSmaller(arr, n);
return 0;
}
|
Java
import java.io.*;
class GFG {
static void printPrevSmaller( int [] arr, int n)
{
System.out.print( "_, " );
for ( int i = 1 ; i < n; i++) {
int j;
for (j = i - 1 ; j >= 0 ; j--) {
if (arr[j] < arr[i]) {
System.out.print(arr[j] + ", " );
break ;
}
}
if (j == - 1 )
System.out.print( "_, " );
}
}
public static void main(String[] args)
{
int [] arr = { 1 , 3 , 0 , 2 , 5 };
int n = arr.length;
printPrevSmaller(arr, n);
}
}
|
Python3
def printPrevSmaller(arr, n):
print ( "_, " , end = "")
for i in range ( 1 , n ):
for j in range (i - 1 , - 2 , - 1 ):
if (arr[j] < arr[i]):
print (arr[j] , ", " ,
end = "")
break
if (j = = - 1 ):
print ( "_, " , end = "")
arr = [ 1 , 3 , 0 , 2 , 5 ]
n = len (arr)
printPrevSmaller(arr, n)
|
C#
using System;
class GFG {
static void printPrevSmaller( int []arr,
int n)
{
Console.Write( "_, " );
for ( int i = 1; i < n; i++)
{
int j;
for (j = i - 1; j >= 0; j--)
{
if (arr[j] < arr[i])
{
Console.Write(arr[j]
+ ", " );
break ;
}
}
if (j == -1)
Console.Write( "_, " ) ;
}
}
public static void Main ()
{
int []arr = {1, 3, 0, 2, 5};
int n = arr.Length;
printPrevSmaller(arr, n);
}
}
|
PHP
<?php
function printPrevSmaller( $arr , $n )
{
echo "_, " ;
for ( $i = 1; $i < $n ; $i ++)
{
$j ;
for ( $j = $i - 1; $j >= 0; $j --)
{
if ( $arr [ $j ] < $arr [ $i ])
{
echo $arr [ $j ] , ", " ;
break ;
}
}
if ( $j == -1)
echo "_, " ;
}
}
$arr = array (1, 3, 0, 2, 5);
$n = count ( $arr );
printPrevSmaller( $arr , $n );
?>
|
Javascript
<script>
function printPrevSmaller( arr, n)
{
document.write( "_, " );
for (let i=1; i<n; i++)
{
let j;
for (j=i-1; j>=0; j--)
{
if (arr[j] < arr[i])
{
document.write(arr[j] + ", " );
break ;
}
}
if (j == -1)
document.write( "_, " );
}
}
let arr = [ 1, 3, 0, 2, 5 ];
let n = arr.length;
printPrevSmaller(arr, n);
</script>
|
Output:
_, 1, _, 0, 2, ,
The time complexity of the above solution is O(n2).
Space Complexity: O(1)
There can be an Efficient Solution that works in O(n) time. The idea is to use a stack. Stack is used to maintain a subsequence of the values that have been processed so far and are smaller than any later value that has already been processed.
Algorithm: Stack-based
Let input sequence be 'arr[]' and size of array be 'n'
1) Create a new empty stack S
2) For every element 'arr[i]' in the input sequence 'arr[]',
where 'i' goes from 0 to n-1.
a) while S is nonempty and the top element of
S is greater than or equal to 'arr[i]':
pop S
b) if S is empty:
'arr[i]' has no preceding smaller value
c) else:
the nearest smaller value to 'arr[i]' is
the top element of S
d) push 'arr[i]' onto S
Below is the implementation of the above algorithm.
C++
#include <iostream>
#include <stack>
using namespace std;
void printPrevSmaller( int arr[], int n)
{
stack< int > S;
for ( int i=0; i<n; i++)
{
while (!S.empty() && S.top() >= arr[i])
S.pop();
if (S.empty())
cout << "_, " ;
else
cout << S.top() << ", " ;
S.push(arr[i]);
}
}
int main()
{
int arr[] = {1, 3, 0, 2, 5};
int n = sizeof (arr)/ sizeof (arr[0]);
printPrevSmaller(arr, n);
return 0;
}
|
Java
import java.util.Stack;
class GFG {
static void printPrevSmaller( int arr[], int n) {
Stack<Integer> S = new Stack<>();
for ( int i = 0 ; i < n; i++) {
while (!S.empty() && S.peek() >= arr[i]) {
S.pop();
}
if (S.empty()) {
System.out.print( "_, " );
} else
{
System.out.print(S.peek() + ", " );
}
S.push(arr[i]);
}
}
public static void main(String[] args) {
int arr[] = { 1 , 3 , 0 , 2 , 5 };
int n = arr.length;
printPrevSmaller(arr, n);
}
}
|
Python3
import math as mt
def printPrevSmaller(arr, n):
S = list ()
for i in range (n):
while ( len (S) > 0 and S[ - 1 ] > = arr[i]):
S.pop()
if ( len (S) = = 0 ):
print ( "_, " , end = "")
else :
print (S[ - 1 ], end = ", " )
S.append(arr[i])
arr = [ 1 , 3 , 0 , 2 , 5 ]
n = len (arr)
printPrevSmaller(arr, n)
|
C#
using System;
using System.Collections.Generic;
public class GFG
{
static void printPrevSmaller( int []arr, int n)
{
Stack< int > S = new Stack< int >();
for ( int i = 0; i < n; i++)
{
while (S.Count != 0 && S.Peek() >= arr[i])
{
S.Pop();
}
if (S.Count == 0)
{
Console.Write( "_, " );
}
else
{
Console.Write(S.Peek() + ", " );
}
S.Push(arr[i]);
}
}
public static void Main(String[] args)
{
int []arr = {1, 3, 0, 2, 5};
int n = arr.Length;
printPrevSmaller(arr, n);
}
}
|
Javascript
<script>
function printPrevSmaller(arr, n)
{
let S = [];
for (let i = 0; i < n; i++)
{
while ((S.length != 0) &&
(S[S.length - 1] >= arr[i]))
{
S.pop();
}
if (S.length == 0)
{
document.write( "_, " );
}
else
{
document.write(S[S.length - 1] + ", " );
}
S.push(arr[i]);
}
}
let arr = [ 1, 3, 0, 2, 5 ];
let n = arr.length;
printPrevSmaller(arr, n);
</script>
|
Output:
_, 1, _, 0, 2,
Time complexity of the above program is O(n) as every element is pushed and popped at most once to the stack. So overall constant number of operations are performed per element.
Auxiliary Space: O(n)
Please write comments if you find the above codes/algorithms incorrect, or find other ways to solve the same problem.
Share your thoughts in the comments
Please Login to comment...