Given an array arr[], find the Previous Greater Element (PGE) for every element in the array.
- The Previous Greater Element of an element x is defined as the first element to its left in the array that is greater than x.
- If no such element exists for a particular position, the PGE should be considered as -1.
Examples:
Input: arr[] = [10, 4, 2, 20, 40, 12]
Output: [-1, 10, 4, -1, -1, 40]
Explanation:
For 10 → No elements on the left → -1
For 4 → Previous greater element is 10 → 10
For 2 → Previous greater element is 4 → 4
For 20 → No element on the left greater than 20 → -1
For 40 → No element on the left greater than 40 → -1
For 12 → Previous greater element is 40 → 40Input: arr[] = [10, 20, 30, 40]
Output: [-1, -1, -1, -1]
Explanation: Since the array is strictly increasing, no element has a greater element before it. Hence, all positions are assigned -1.
Table of Content
[Naive Solution] - Nested Loops - O(n2) Time and O(1) Space
The idea is to use two loops: for each element, check the remaining elements on its right to find the next greater one. If none exists, store -1.
#include <iostream>
#include <vector>
using namespace std;
vector<int> preGreaterEle(vector<int>& arr) {
int n = arr.size();
// initialize all PGEs as -1
vector<int> result(n, -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 greater element on the left
result[i] = arr[j];
break;
}
}
}
return result;
}
int main() {
vector<int> arr = {10, 4, 2, 20, 40, 12};
vector<int> pge = preGreaterEle(arr);
for (int x : pge) {
cout << x << " ";
}
cout << endl;
return 0;
}
#include <stdio.h>
#include <stdlib.h>
int* preGreaterEle(int arr[], int n) {
// allocate memory for result array
int* result = (int*)malloc(n * sizeof(int));
// initialize all PGEs 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 greater element on the left
result[i] = arr[j];
break;
}
}
}
return result;
}
int main() {
int arr[] = {10, 4, 2, 20, 40, 12};
int n = sizeof(arr) / sizeof(arr[0]);
int* result = preGreaterEle(arr, n);
for (int i = 0; i < n; i++) printf("%d ", result[i]);
return 0;
}
import java.util.ArrayList;
class GfG {
static ArrayList<Integer> preGreaterEle(int[] arr) {
int n = arr.length;
// initialize all PGEs as -1
ArrayList<Integer> result = new ArrayList<>();
for (int i = 0; i < n; i++) result.add(-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 greater element on the left
result.set(i, arr[j]);
break;
}
}
}
return result;
}
public static void main(String[] args) {
int[] arr = {10, 4, 2, 20, 40, 12};
ArrayList<Integer> pge = preGreaterEle(arr);
for (int x : pge) System.out.print(x + " ");
System.out.println();
}
}
def preGreaterEle(arr):
n = len(arr)
# initialize all PGEs as -1
result = [-1] * n
for i in range(n):
# check all elements on the left
for j in range(i - 1, -1, -1):
if arr[j] > arr[i]:
# first greater element on the left
result[i] = arr[j]
break
return result
if __name__ == "__main__":
arr = [10, 4, 2, 20, 40, 12]
pge = preGreaterEle(arr)
for x in pge:
print(x, end=" ")
print()
using System;
using System.Collections.Generic;
class GfG {
public static List<int> preGreaterEle(int[] arr) {
int n = arr.Length;
// initialize all PGEs as -1
List<int> result = new List<int>();
for (int i = 0; i < n; i++) result.Add(-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 greater element on the left
result[i] = arr[j];
break;
}
}
}
return result;
}
public static void Main() {
int[] arr = {10, 4, 2, 20, 40, 12};
List<int> pge = preGreaterEle(arr);
foreach (int x in pge) Console.Write(x + " ");
Console.WriteLine();
}
}
function preGreaterEle(arr) {
let n = arr.length;
// initialize all PGEs as -1
let result = new Array(n).fill(-1);
for (let i = 0; i < n; i++) {
// check all elements on the left
for (let j = i - 1; j >= 0; j--) {
if (arr[j] > arr[i]) {
// first greater element on the left
result[i] = arr[j];
break;
}
}
}
return result;
}
// Driver Code
let arr = [10, 4, 2, 20, 40, 12];
let pge = preGreaterEle(arr);
console.log(pge.join(" "));
Output
-1 10 4 -1 -1 40
[Expected Solution] Using Monotonic Stack - O(n) Time and O(n) Space
The idea is to use a monotonic decreasing stack. We traverse the array from left to right. For each element, we pop elements from the stack that are smaller than or equal to it, since they cannot be the previous greater element. If the stack is not empty, the top of the stack is the previous greater element. Finally, we push the current element onto the stack.
#include <iostream>
#include <vector>
#include <stack>
using namespace std;
vector<int> preGreaterEle(vector<int>& arr) {
int n = arr.size();
// initialize all PGEs as -1
vector<int> result(n, -1);
// stack to keep track of elements
stack<int> st;
// traverse the array from left to right
for (int i = 0; i < n; i++) {
// pop elements from stack which are <= current element
while (!st.empty() && st.top() <= arr[i]) {
st.pop();
}
// if stack is not empty, top element is PGE
if (!st.empty()) {
result[i] = st.top();
}
// push current element onto stack
st.push(arr[i]);
}
return result;
}
int main() {
vector<int> arr = {10, 4, 2, 20, 40, 12};
vector<int> pge = preGreaterEle(arr);
for (int x : pge) {
cout << x << " ";
}
cout << endl;
return 0;
}
import java.util.ArrayList;
import java.util.Stack;
import java.util.Collections;
class Solution {
static ArrayList<Integer> preGreaterEle(int[] arr) {
int n = arr.length;
// initialize all PGEs as -1
ArrayList<Integer> result = new ArrayList<>(Collections.nCopies(n, -1));
// stack to keep track of elements
Stack<Integer> st = new Stack<>();
// traverse the array from left to right
for (int i = 0; i < n; i++) {
// pop elements from stack which are <= current element
while (!st.isEmpty() && st.peek() <= arr[i]) {
st.pop();
}
// if stack is not empty, top element is PGE
if (!st.isEmpty()) {
result.set(i, st.peek());
}
// push current element onto stack
st.push(arr[i]);
}
return result;
}
public static void main(String[] args) {
int[] arr = {10, 4, 2, 20, 40, 12};
ArrayList<Integer> pge = preGreaterEle(arr);
for (int x : pge) {
System.out.print(x + " ");
}
System.out.println();
}
}
def preGreaterEle(arr):
n = len(arr)
# initialize all PGEs as -1
result = [-1] * n
# stack to keep track of elements
st = []
# traverse the array from left to right
for i in range(n):
# pop elements from stack which are <= current element
while st and st[-1] <= arr[i]:
st.pop()
# if stack is not empty, top element is PGE
if st:
result[i] = st[-1]
# push current element onto stack
st.append(arr[i])
return result
if __name__ == "__main__":
arr = [10, 4, 2, 20, 40, 12]
pge = preGreaterEle(arr)
for x in pge:
print(x, end=" ")
print()
using System;
using System.Collections.Generic;
class GfG {
public static List<int> preGreaterEle(int[] arr) {
int n = arr.Length;
// initialize all PGEs as -1
List<int> result = new List<int>();
for (int i = 0; i < n; i++) result.Add(-1);
// stack to keep track of elements
Stack<int> st = new Stack<int>();
// traverse the array from left to right
for (int i = 0; i < n; i++) {
// pop elements from stack which are <= current element
while (st.Count > 0 && st.Peek() <= arr[i]) st.Pop();
// if stack is not empty, top element is PGE
if (st.Count > 0) result[i] = st.Peek();
// push current element onto stack
st.Push(arr[i]);
}
return result;
}
public static void Main() {
int[] arr = {10, 4, 2, 20, 40, 12};
List<int> pge = preGreaterEle(arr);
foreach (int x in pge) Console.Write(x + " ");
Console.WriteLine();
}
}
function preGreaterEle(arr) {
let n = arr.length;
// initialize all PGEs as -1
let result = new Array(n).fill(-1);
// stack to keep track of elements
let st = [];
// traverse the array from left to right
for (let i = 0; i < n; i++) {
// pop elements from stack which are <= current element
while (st.length > 0 && st[st.length - 1] <= arr[i]) {
st.pop();
}
// if stack is not empty, top element is PGE
if (st.length > 0) result[i] = st[st.length - 1];
// push current element onto stack
st.push(arr[i]);
}
return result;
}
// Driver Code
let arr = [10, 4, 2, 20, 40, 12];
let pge = preGreaterEle(arr);
console.log(pge.join(" "));
Output
-1 10 4 -1 -1 40