Nearest smaller numbers on left side in an array
Last Updated : 05 Apr, 2025
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);
[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);
Similar Reads
Farthest Right Smaller for all in an Array Given an array arr[] of size n. For every element in the array, your task is to find the index of the farthest element in the array to the right which is smaller than the current element. If no such number exists then return -1. Examples: Input: arr[] = [3, 1, 5, 2, 4] Output: [3, -1, 4, -1, -1] Exp
9 min read
Nearest prime number in the array of every array element Given an integer array arr[] consisting of N integers, the task is to find the nearest Prime Number in the array for every element in the array. If the array does not contain any prime number, then print -1. Examples: Input: arr[] = {1, 2, 3, 1, 6} Output: 2 2 3 3 3 Explanation: For the subarray {1,
11 min read
Find the Target number in an Array Finding a number within an array is an operation, in the field of computer science and data analysis. In this article, we will discuss the steps involved and analyze their time and space complexities. Examples: Input: Array: {10, 20, 30, 40, 50} , Target: 30Output: "Target found at index 2" Input: A
13 min read
Find the nearest value present on the left of every array element 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 2Explanation:[2], it is the only number in this prefix. He
8 min read
Count smaller elements on Right side Given an unsorted array arr[] of distinct integers, construct another array countSmaller[] such that countSmaller[i] contains the count of smaller elements on the right side of each element arr[i] in the array. Examples: Input: arr[] = {12, 1, 2, 3, 0, 11, 4}Output: countSmaller[] = {6, 1, 1, 1, 0,
15+ min read