Given an integer array, find the previous smaller element for every array element. The previous smaller element of a number x is the first smaller number to the left of x in the array.

In other words, for each element A[i] in the array A, find an element A[j] such that j < i and A[j] < A[i] and value of j should be as maximum as possible. If the previous smaller element doesn't in the array for any element, consider it -1.

 
For example,

Input:  [2, 5, 3, 7, 8, 1, 9]
Output: [-1, 2, 2, 3, 7, -1, 1]
 
 
Input:  [5, 7, 4, 9, 8, 10]
Output: [-1, 5, -1, 4, 4, 8]
 
 
Note that the first element always has a previous smaller element as -1.

Practice this problem

1. Brute-Force Approach

The idea is to use two nested loops. The outer loop takes each array element from left to right. The inner loop runs from right to left and considers all elements to the "left" of the element picked by the outer loop. Terminate the inner loop as soon as the smaller element is found, which would be the previous smaller element for the element picked by the outer loop.

The time complexity of this approach is O(n2), where n is the size of the input. Following is the implementation in C, Java, and Python based on the above idea:

C


Download  Run Code

Output:

-1 2 2 3 7 -1 1

Java


Download  Run Code

Output:

-1 2 2 3 7 -1 1

Python


Download  Run Code

Output:

-1 2 2 3 7 -1 1

2. Using Stack

We can reduce the time complexity to linear by using extra space. The idea is to use a stack, which is a LIFO (Last–In, First–Out) data structure suitable for this problem. Following is the C++, Java, and Python program that demonstrates the algorithm:

C++


Download  Run Code

Output:

-1 2 2 3 7 -1 1

Java


Download  Run Code

Output:

-1 2 2 3 7 -1 1

Python


Download  Run Code

Output:

-1 2 2 3 7 -1 1

The time complexity of the above solution is O(n) since every element is pushed and popped at most once to the stack. The additional space used by the program is O(n) for the stack.