Previous Smaller Element (original) (raw)
Last Updated : 12 Sep, 2025
Given an array **arr[], find the **Previous Smaller Element (PSE) for every element in the array.
- The Previous Smaller Element of an element x is defined as the first element to its left in the array that is smaller than x.
- If no such element exists for a particular position, the PSE should be considered as -1.
**Examples:
**Input: arr[] = [1, 6, 2]
**Output: [-1, 1, 1]
**Explanation: For the first element 1, there is no element to its left, so the result is -1. For 6, the previous smaller element is 1. For 2, the previous smaller element is also 1, since it is the closest smaller number when looking left.**Input: arr[] = [1, 5, 0, 3, 4, 5]
**Output: [-1, 1, -1, 0, 3, 4]
**Explanation:
For 1, no element on the left → -1
For 5, the previous smaller element is 1
For 0, no smaller element on the left → -1
For 3, the previous smaller element is 0
For 4, the previous smaller element is 3
For the last 5, the previous smaller element is 4
Table of Content
- [Naive Approach] Using Nested Loops - O(n^2) Time and O(1) Space
- [Expected Approach] Stack-based Approach (Monotonic stack)
[Naive Approach] Using Nested Loops - O(n2) Time and O(1) Space
The idea is to use two loops: for each element, check the elements on its left to find the previous smaller one. If none exists, store -1.
C++ `
#include #include using namespace std;
vector prevSmaller(vector& arr){ int n = arr.size(); vector result(n, -1);
// for each element, check all elements
// on the left
for (int i = 0; i < n; i++) {
for (int j = i - 1; j >= 0; j--) {
if (arr[j] < arr[i]) {
result[i] = arr[j];
break;
}
}
}
return result;}
int main() { vector arr = {1, 5, 0, 3, 4, 5}; vector ans = prevSmaller(arr);
for (int x : ans) cout << x << " ";
return 0;}
C
#include <stdio.h> #include <stdlib.h>
int* prevSmaller(int arr[], int n) {
// allocate memory for result array
int* result = (int*)malloc(n * sizeof(int));
// initialize all PSEs as -1
for (int i = 0; i < n; i++) result[i] = -1;
for (int i = 0; i < n; i++) {
// check all elements on the left
for (int j = i - 1; j >= 0; j--) {
if (arr[j] < arr[i]) {
// first smaller element on the left
result[i] = arr[j];
break;
}
}
}
return result;}
int main() { int arr[] = {1, 5, 0, 3, 4, 5}; int n = sizeof(arr) / sizeof(arr[0]);
int* result = prevSmaller(arr, n);
for (int i = 0; i < n; i++) {
printf("%d ", result[i]);
}
printf("\n");
return 0;}
Java
import java.util.ArrayList;
class GfG { static ArrayList prevSmaller(int arr[]) { int n = arr.length; ArrayList result = new ArrayList<>();
// initialize all as -1
for (int i = 0; i < n; i++) result.add(-1);
// for each element, check all elements
// on the left
for (int i = 0; i < n; i++) {
for (int j = i - 1; j >= 0; j--) {
if (arr[j] < arr[i]) {
result.set(i, arr[j]);
break;
}
}
}
return result;
}
public static void main(String[] args) {
int arr[] = {1, 5, 0, 3, 4, 5};
ArrayList<Integer> ans = prevSmaller(arr);
for (int x : ans) System.out.print(x + " ");
}}
Python
def prevSmaller(arr): n = len(arr) result = [-1] * n
# for each element, check all elements
# on the left
for i in range(n):
for j in range(i - 1, -1, -1):
if arr[j] < arr[i]:
result[i] = arr[j]
break
return resultif name == "main": arr = [1, 5, 0, 3, 4, 5] ans = prevSmaller(arr)
for x in ans:
print(x, end=" ")C#
using System; using System.Collections.Generic;
class GfG { static List prevSmaller(int[] arr) { int n = arr.Length; List result = new List(new int[n]);
// initialize all as -1
for (int i = 0; i < n; i++) result[i] = -1;
// for each element, check all elements
// on the left
for (int i = 0; i < n; i++) {
for (int j = i - 1; j >= 0; j--) {
if (arr[j] < arr[i]) {
result[i] = arr[j];
break;
}
}
}
return result;
}
public static void Main() {
int[] arr = {1, 5, 0, 3, 4, 5};
List<int> ans = prevSmaller(arr);
foreach (int x in ans) Console.Write(x + " ");
}}
JavaScript
function prevSmaller(arr) { let n = arr.length; let result = new Array(n).fill(-1);
// for each element, check all elements
// on the left
for (let i = 0; i < n; i++) {
for (let j = i - 1; j >= 0; j--) {
if (arr[j] < arr[i]) {
result[i] = arr[j];
break;
}
}
}
return result;}
// Driver Code let arr = [1, 5, 0, 3, 4, 5]; let ans = prevSmaller(arr); console.log(ans.join(" "));
`
[Expected Approach] Using Monotonic stack - O(n) Time and O(n) Space
The idea is to use a monotonic increasing stack. We traverse the array from left to right. For each element, we pop elements from the stack that are greater than or equal to it, since they cannot be the previous smaller element. If the stack is not empty, the top of the stack is the previous smaller element. Finally, we push the current element onto the stack.
C++ `
#include #include #include using namespace std;
vector prevSmaller(vector& arr) { int n = arr.size(); vector result(n, -1);
stack<int> st;
for (int i = 0; i < n; i++) {
// pop elements from stack until a smaller
// element is found or stack becomes empty
while (!st.empty() && st.top() >= arr[i]) {
st.pop();
}
// if stack is not empty, top is nearest smaller
if (!st.empty()) {
result[i] = st.top();
}
// push current element to stack
st.push(arr[i]);
}
return result;}
int main() { vector arr = {1, 5, 0, 3, 4, 5}; vector ans = prevSmaller(arr);
for (int x : ans) cout << x << " ";
return 0;}
C
#include <stdio.h> #include <stdlib.h>
int* prevSmaller(int arr[], int n) {
int* result = (int*)malloc(n * sizeof(int));
// stack to keep track of elements
int* st = (int*)malloc(n * sizeof(int));
int top = -1;
// initialize all PSEs as -1
for (int i = 0; i < n; i++) {
result[i] = -1;
}
for (int i = 0; i < n; i++) {
// pop elements from stack which are >= current element
while (top >= 0 && st[top] >= arr[i]) {
top--;
}
// if stack is not empty, top element is PSE
if (top >= 0) {
result[i] = st[top];
}
// push current element onto stack
st[++top] = arr[i];
}
return result;}
int main() { int arr[] = {1, 5, 0, 3, 4, 5}; int n = sizeof(arr) / sizeof(arr[0]);
int* result = prevSmaller(arr, n);
for (int i = 0; i < n; i++) {
printf("%d ", result[i]);
}
printf("\n");
return 0;}
Java
import java.util.ArrayList; import java.util.Stack;
class GfG { static ArrayList prevSmaller(int arr[]) { int n = arr.length; ArrayList result = new ArrayList<>();
// initialize all as -1
for (int i = 0; i < n; i++) result.add(-1);
Stack<Integer> st = new Stack<>();
for (int i = 0; i < n; i++) {
// pop elements from stack until a smaller
// element is found or stack becomes empty
while (!st.isEmpty() && st.peek() >= arr[i]) {
st.pop();
}
// if stack is not empty, top is nearest smaller
if (!st.isEmpty()) {
result.set(i, st.peek());
}
// push current element to stack
st.push(arr[i]);
}
return result;
}
public static void main(String[] args) {
int arr[] = {1, 5, 0, 3, 4, 5};
ArrayList<Integer> ans = prevSmaller(arr);
for (int x : ans) System.out.print(x + " ");
}}
Python
def prevSmaller(arr): n = len(arr) result = [-1] * n
# stack to keep track of elements
st = []
for i in range(n):
# pop elements from stack until a smaller
# element is found or stack becomes empty
while st and st[-1] >= arr[i]:
st.pop()
# if stack is not empty, top is nearest smaller
if st:
result[i] = st[-1]
# push current element to stack
st.append(arr[i])
return resultif name == "main": arr = [1, 5, 0, 3, 4, 5] ans = prevSmaller(arr)
for x in ans:
print(x, end=" ")C#
using System; using System.Collections.Generic;
class GfG { static List prevSmaller(int[] arr) { int n = arr.Length; List result = new List(new int[n]);
// initialize all as -1
for (int i = 0; i < n; i++) result[i] = -1;
Stack<int> st = new Stack<int>();
for (int i = 0; i < n; i++) {
// pop elements from stack until a smaller
// element is found or stack becomes empty
while (st.Count > 0 && st.Peek() >= arr[i]) {
st.Pop();
}
// if stack is not empty, top is nearest smaller
if (st.Count > 0) {
result[i] = st.Peek();
}
// push current element to stack
st.Push(arr[i]);
}
return result;
}
public static void Main() {
int[] arr = {1, 5, 0, 3, 4, 5};
List<int> ans = prevSmaller(arr);
foreach (int x in ans) Console.Write(x + " ");
}}
JavaScript
function prevSmaller(arr) { let n = arr.length; let result = new Array(n).fill(-1);
// stack to keep track of elements
let st = [];
for (let i = 0; i < n; i++) {
// pop elements from stack until a smaller
// element is found or stack becomes empty
while (st.length > 0 && st[st.length - 1] >= arr[i]) {
st.pop();
}
// if stack is not empty, top is nearest smaller
if (st.length > 0) {
result[i] = st[st.length - 1];
}
// push current element to stack
st.push(arr[i]);
}
return result;}
// Driver Code let arr = [1, 5, 0, 3, 4, 5]; let ans = prevSmaller(arr); console.log(ans.join(" "));
`