Open In App

Nearest smaller numbers on left side in an array

Last Updated : 05 Apr, 2025
Comments
Improve
Suggest changes
Like Article
Like
Report

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, 2]
Output: [-1, 1, 1,]
Explanation: There is no number at the left of 1. Smaller number than 6 and 2 is 1.

Input: arr = [1, 5, 0, 3, 4, 5]
Output: [-1, 1, -1, 0, 3, 4]
Explanation: Upto 3 it is easy to see the smaller numbers. But for 4 the smaller numbers are 1, 0 and 3. But among them 3 is closest. Similarly for 5 it is 4.

[Naive Approach] Using Nested Loops – O(n^2) Time and O(1) Space

We 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>
#include <vector>
using namespace std;

void prevSmaller(const vector<int>& arr)
{
    // Always print -1 for the first element
    cout << "-1 ";

    // Start from second element
    for (int i = 1; i < arr.size(); i++) {
        int j;

        // Look for a smaller element on the left of 'i'
        for (j = i - 1; j >= 0; j--) {
            if (arr[j] < arr[i]) {
                cout << arr[j] << " ";
                break;
            }
        }

        // If there is no smaller element on left of 'i', print -1
        if (j == -1)
            cout << "-1 ";
    }
}

int main()
{
    vector<int> arr = {1, 5, 0, 3, 4, 5}; 
    prevSmaller(arr);
    return 0;
}
C
#include <stdio.h>
#include <stdbool.h>

void prevSmaller(int arr[], int size) {
    // Always print -1 for the first element
    printf("-1 ");

    // Start from second element
    for (int i = 1; i < size; i++) {
        int j;

        // Look for a smaller element on the left of 'i'
        for (j = i - 1; j >= 0; j--) {
            if (arr[j] < arr[i]) {
                printf("%d ", arr[j]);
                break;
            }
        }

        // If there is no smaller element on left of 'i', print -1
        if (j == -1)
            printf("-1 ");
    }
}

int main() {
    int arr[] = {1, 5, 0, 3, 4, 5};
    int size = sizeof(arr) / sizeof(arr[0]);
    prevSmaller(arr, size);
    return 0;
}
Java
import java.util.Arrays;

public class GfG {
    public static void prevSmaller(int[] arr) {
        // Always print -1 for the first element
        System.out.print("-1 ");

        // Start from second element
        for (int i = 1; i < arr.length; i++) {
            int j;

            // Look for a smaller element on the left of 'i'
            for (j = i - 1; j >= 0; j--) {
                if (arr[j] < arr[i]) {
                    System.out.print(arr[j] + " ");
                    break;
                }
            }

            // If there is no smaller element on left of 'i', print -1
            if (j == -1)
                System.out.print("-1 ");
        }
    }

    public static void main(String[] args) {
        int[] arr = {1, 5, 0, 3, 4, 5};
        prevSmaller(arr);
    }
}
Python
def prevSmaller(arr):
    # Always print -1 for the first element
    print("-1", end=' ')

    # Start from second element
    for i in range(1, len(arr)):
        # Look for a smaller element on the left of 'i'
        for j in range(i - 1, -1, -1):
            if arr[j] < arr[i]:
                print(arr[j], end=' ')
                break
        else:
            # If there is no smaller element on left of 'i', print -1
            print("-1", end=' ')

arr = [1, 5, 0, 3, 4, 5]
prevSmaller(arr)
C#
using System;

class GfG {
    static void PrevSmaller(int[] arr) {
        // Always print -1 for the first element
        Console.Write("-1 ");

        // Start from second element
        for (int i = 1; i < arr.Length; i++) {
            int j;

            // Look for a smaller element on the left of 'i'
            for (j = i - 1; j >= 0; j--) {
                if (arr[j] < arr[i]) {
                    Console.Write(arr[j] + " ");
                    break;
                }
            }

            // If there is no smaller element on left of 'i', print -1
            if (j == -1)
                Console.Write("-1 ");
        }
    }

    static void Main() {
        int[] arr = {1, 5, 0, 3, 4, 5};
        PrevSmaller(arr);
    }
}
JavaScript
function prevSmaller(arr) {
    // Always print -1 for the first element
    process.stdout.write("-1 ");

    // Start from second element
    for (let i = 1; i < arr.length; i++) {
        let found = false;

        // Look for a smaller element on the left of 'i'
        for (let j = i - 1; j >= 0; j--) {
            if (arr[j] < arr[i]) {
                process.stdout.write(` ${arr[j]}`);
                found = true;
                break;
            }
        }

        // If there is no smaller element on left of 'i', print -1
        if (!found)
            process.stdout.write(" -1");
    }
}

const arr = [1, 5, 0, 3, 4, 5];
prevSmaller(arr);

Output
-1 1 -1 0 3 4 

[Expected Approach] Using Stack- O(n) Time and O(n) Space

If we traverse the array from left to right, then for the current element, there can be two cases.
1) The element is greater than the previous element, then the nearest smaller for current element is the previous element,
2) The element is smaller than the previous element. In this case, the smaller element can be anywhere. But one thing to note is that the previous elements that are greater than the current element are never going to smaller elements for any of the upcoming elements and hence need not to be stored.

The idea is to use a stack to store the potential smaller elements that we have seen so far. We use stack (LIFO) as we need the most recently seen smaller. We remove top of the stack one by one while the top is greater than the current element. When we find a smaller element, we print it. One important observation is, the stack will always have elements in increasing order as we remove greater elements before pushing.

1. Create a new empty stack s.

2. Iterate over each element arr[i] in the array arr[] (from 0 to n-1).

  • While the stack s is non-empty and the top element of the stack is greater than or equal to arr[i], pop the stack. This ensures that we are left with only the elements in the stack that are smaller than arr[i].
  • If the stack is empty after popping, then arr[i] has no preceding smaller element. In this case, print -1.
  • If the stack is not empty, the nearest smaller element to arr[i] is the top element of the stack. Print the top element.
  • Push arr[i] onto the stack for future comparisons.
C++
#include <iostream>
#include <vector>
#include <stack>
using namespace std;

void prevSmaller(vector<int>& arr)
{
    stack<int> s;

    for (int i = 0; i < arr.size(); i++)
    {
        while (!s.empty() && s.top() >= arr[i])
            s.pop();

        if (s.empty())
            cout << "-1 ";
        else
            cout << s.top() << " ";

        s.push(arr[i]);
    }
}

int main()
{
    vector<int> arr = {1, 5, 0, 3, 4, 5};
    prevSmaller(arr);
    return 0;
}
C
#include <stdio.h>
#include <stdlib.h>

void prevSmaller(int* arr, int n) {
    int* s = (int*)malloc(n * sizeof(int));
    int top = -1;

    for (int i = 0; i < n; i++) {
        while (top != -1 && s[top] >= arr[i])
            top--;

        if (top == -1)
            printf("-1 ");
        else
            printf("%d ", s[top]);

        s[++top] = arr[i];
    }
    free(s);
}

int main() {
    int arr[] = {1, 5, 0, 3, 4, 5};
    int n = sizeof(arr) / sizeof(arr[0]);
    prevSmaller(arr, n);
    return 0;
}
Java
import java.util.Stack;

public class GfG {
    public static void prevSmaller(int[] arr) {
        Stack<Integer> s = new Stack<>();

        for (int i = 0; i < arr.length; i++) {
            while (!s.isEmpty() && s.peek() >= arr[i])
                s.pop();

            if (s.isEmpty())
                System.out.print("-1 ");
            else
                System.out.print(s.peek() + " ");

            s.push(arr[i]);
        }
    }

    public static void main(String[] args) {
        int[] arr = {1, 5, 0, 3, 4, 5};
        prevSmaller(arr);
    }
}
Python
def prev_smaller(arr):
    s = []
    for i in range(len(arr)):
        while s and s[-1] >= arr[i]:
            s.pop()

        if not s:
            print(-1, end=' ')
        else:
            print(s[-1], end=' ')

        s.append(arr[i])

if __name__ == '__main__':
    arr = [1, 5, 0, 3, 4, 5]
    prev_smaller(arr)
C#
using System;
using System.Collections.Generic;

class GfG {
    public static void PrevSmallerElements(int[] arr) {
        Stack<int> s = new Stack<int>();

        for (int i = 0; i < arr.Length; i++) {
            while (s.Count > 0 && s.Peek() >= arr[i])
                s.Pop();

            if (s.Count == 0)
                Console.Write("-1 ");
            else
                Console.Write(s.Peek() + " ");

            s.Push(arr[i]);
        }
    }

    static void Main() {
        int[] arr = {1, 5, 0, 3, 4, 5};
        PrevSmallerElements(arr);
    }
}
JavaScript
function prevSmaller(arr) {
    const s = [];
    arr.forEach((num) => {
        while (s.length && s[s.length - 1] >= num) {
            s.pop();
        }

        if (s.length === 0) {
            process.stdout.write("-1 ");
        } else {
            process.stdout.write(s[s.length - 1] + " ");
        }

        s.push(num);
    });
}

const arr = [1, 5, 0, 3, 4, 5];
prevSmaller(arr);

Output
-1 1 -1 0 3 4 


Next Article
Article Tags :
Practice Tags :

Similar Reads