Given an array of integers, replace every element with the least greater element on its right side in the array. If there are no greater elements on the right side, replace it with -1.
Input: arr[] = [2, 6, 9, 1, 3, 2]
Output: [3, 9, -1, 2, -1, -1]
Explanation: The least next greater element of 2 is 3. The least next greater element of 6 is 9.least next greater element for 9 does not exist and so on.Input: arr[] = [8, 58, 71, 18, 31, 32, 63, 92, 43, 3, 91, 93, 25, 80, 28]
Output: [18, 63, 80, 25, 32, 43, 80, 93, 80, 25, 93, -1, 28, -1, -1]
Explanation: The least next greater element of 8 is 18. The least next greater element of 58 is 63 and so on.
Table of Content
[Naive Approach] Using Nested Loops – O(n²) Time and O(n) Space
For every element, check all elements to its right and find the smallest element greater than it. For each index, we scan the remaining array and track the minimum value that satisfies the condition. If no such element exists, we keep
-1.
- For each element, iterate through all elements to its right
- Find elements greater than the current one and track the smallest among them
- Store the result for each index, or
-1if no such element exists
#include <iostream>
#include <vector>
using namespace std;
vector<int> findLeastGreater(vector<int>& arr) {
int n = arr.size();
vector<int> res(n, -1);
for (int i = 0; i < n; i++) {
int best = -1;
for (int j = i + 1; j < n; j++) {
if (arr[j] > arr[i]) {
if (best == -1 || arr[j] < best) {
best = arr[j];
}
}
}
res[i] = best;
}
return res;
}
int main() {
vector<int> arr = {8, 58, 71, 18, 31, 32, 63, 92, 43, 3, 91, 93, 25, 80, 28};
vector<int> result = findLeastGreater(arr);
for (int x : result) {
cout << x << " ";
}
return 0;
}
import java.util.*;
class GFG {
static int[] findLeastGreater(int[] arr) {
int n = arr.length;
int[] res = new int[n];
Arrays.fill(res, -1);
for (int i = 0; i < n; i++) {
int best = -1;
for (int j = i + 1; j < n; j++) {
if (arr[j] > arr[i]) {
if (best == -1 || arr[j] < best) {
best = arr[j];
}
}
}
res[i] = best;
}
return res;
}
public static void main(String[] args) {
int[] arr = {8, 58, 71, 18, 31, 32, 63, 92, 43, 3, 91, 93, 25, 80, 28};
int[] result = findLeastGreater(arr);
for (int x : result) {
System.out.print(x + " ");
}
}
}
def findLeastGreater(arr):
n = len(arr)
res = [-1] * n
for i in range(n):
best = -1
for j in range(i + 1, n):
if arr[j] > arr[i]:
if best == -1 or arr[j] < best:
best = arr[j]
res[i] = best
return res
# Driver code
arr = [8, 58, 71, 18, 31, 32, 63, 92, 43, 3, 91, 93, 25, 80, 28]
result = findLeastGreater(arr)
for x in result:
print(x, end=" ")
using System;
class GFG {
static int[] findLeastGreater(int[] arr) {
int n = arr.Length;
int[] res = new int[n];
for (int i = 0; i < n; i++)
res[i] = -1;
for (int i = 0; i < n; i++) {
int best = -1;
for (int j = i + 1; j < n; j++) {
if (arr[j] > arr[i]) {
if (best == -1 || arr[j] < best) {
best = arr[j];
}
}
}
res[i] = best;
}
return res;
}
public static void Main() {
int[] arr = {8, 58, 71, 18, 31, 32, 63, 92, 43, 3, 91, 93, 25, 80, 28};
int[] result = findLeastGreater(arr);
foreach (int x in result) {
Console.Write(x + " ");
}
}
}
function findLeastGreater(arr) {
let n = arr.length;
let res = new Array(n).fill(-1);
for (let i = 0; i < n; i++) {
let best = -1;
for (let j = i + 1; j < n; j++) {
if (arr[j] > arr[i]) {
if (best === -1 || arr[j] < best) {
best = arr[j];
}
}
}
res[i] = best;
}
return res;
}
// Driver code
let arr = [8, 58, 71, 18, 31, 32, 63, 92, 43, 3, 91, 93, 25, 80, 28];
let result = findLeastGreater(arr);
for (let x of result) {
process.stdout.write(x + " ");
}
[Efficient Approach] Using Set (Balanced BST) – O(n log n) Time and O(n) Space
The idea is to traverse the array from right to left while maintaining a sorted set of elements seen so far. For each element, we find the smallest element greater than it in O(Log n) time. Since the set is always sorted, this gives the required least greater element efficiently without scanning all elements on the right.
- Traverse the array from right to left
- Use a set to keep elements in sorted order
- For each element, find the least greater element in O(Log n) time.
- Store the result and insert the current element into the set
#include <bits/stdc++.h>
using namespace std;
// Function to replace every element with the
// least greater element on its right
vector<int> findLeastGreater(vector<int>& arr)
{
int n = arr.size();
vector<int> res(n, -1);
set<int> treeset;
for (int i = n - 1; i >= 0; i--) {
auto it = treeset.upper_bound(arr[i]);
if (it != treeset.end())
res[i] = *it;
treeset.insert(arr[i]);
}
return res;
}
// Driver Program to test above functions
int main()
{
vector<int> arr = { 8, 58, 71, 18, 31, 32, 63, 92,
43, 3, 91, 93, 25, 80, 28 };
vector<int> res = findLeastGreater(arr);
for (int x : res)
cout << x << " ";
return 0;
}
import java.util.*;
class GFG {
// Function to replace every element with the
// least greater element on its right
static int[] findLeastGreater(int[] arr)
{
int n = arr.length;
int[] res = new int[n];
Arrays.fill(res, -1);
TreeSet<Integer> treeset = new TreeSet<>();
for (int i = n - 1; i >= 0; i--) {
Integer val = treeset.higher(arr[i]);
if (val != null)
res[i] = val;
treeset.add(arr[i]);
}
return res;
}
// Driver Program to test above functions
public static void main(String[] args)
{
int[] arr = { 8, 58, 71, 18, 31, 32, 63, 92,
43, 3, 91, 93, 25, 80, 28 };
int[] res = findLeastGreater(arr);
for (int x : res)
System.out.print(x + " ");
}
}
# Function to replace every element with the
# least greater element on its right
from bisect import bisect_right, insort
def findLeastGreater(arr):
n = len(arr)
res = [-1] * n
sortedset = []
for i in range(n - 1, -1, -1):
idx = bisect_right(sortedset, arr[i])
if idx < len(sortedset):
res[i] = sortedset[idx]
insort(sortedset, arr[i])
return res
# Driver Program
arr = [8, 58, 71, 18, 31, 32, 63, 92,
43, 3, 91, 93, 25, 80, 28]
res = findLeastGreater(arr)
for x in res:
print(x, end=" ")
using System;
using System.Collections.Generic;
class GFG {
// Function to replace every element with the
// least greater element on its right
static int[] findLeastGreater(int[] arr)
{
int n = arr.Length;
int[] res = new int[n];
for (int i = 0; i < n; i++) res[i] = -1;
SortedSet<int> treeset = new SortedSet<int>();
for (int i = n - 1; i >= 0; i--) {
foreach (int val in treeset) {
if (val > arr[i]) {
res[i] = val;
break;
}
}
treeset.Add(arr[i]);
}
return res;
}
// Driver Program
public static void Main()
{
int[] arr = { 8, 58, 71, 18, 31, 32, 63, 92,
43, 3, 91, 93, 25, 80, 28 };
int[] res = findLeastGreater(arr);
foreach (int x in res)
Console.Write(x + " ");
}
}
// Function to replace every element with the
// least greater element on its right
function findLeastGreater(arr)
{
let n = arr.length;
let res = new Array(n).fill(-1);
let sortedset = [];
function upperBound(arr, target) {
let l = 0, r = arr.length;
while (l < r) {
let mid = Math.floor((l + r) / 2);
if (arr[mid] <= target) l = mid + 1;
else r = mid;
}
return l;
}
for (let i = n - 1; i >= 0; i--) {
let idx = upperBound(sortedset, arr[i]);
if (idx < sortedset.length)
res[i] = sortedset[idx];
sortedset.splice(idx, 0, arr[i]); // insert sorted
}
return res;
}
// Driver Program
let arr = [8, 58, 71, 18, 31, 32, 63, 92,
43, 3, 91, 93, 25, 80, 28];
let res = findLeastGreater(arr);
for (let x of res)
process.stdout.write(x + " ");
Output
18 63 80 25 32 43 80 93 80 25 93 -1 28 -1 -1
[Optimized Approach] Using Sorting + Stack (Next Greater Index) – O(n log n) Time and O(n) Space
The idea is to transform the problem into a “next greater index” problem. We store elements along with their indices and sort them by value. Then, using a stack, we find the next greater index for each element. Since sorting ensures we process smaller elements first, the next valid index we assign will correspond to the least greater element on the right.
- Store array elements with their indices and sort them by value (handle duplicates carefully)
- Use a stack to find the next greater index for each position
- Map these indices back to actual values in the original array
- Fill result array with corresponding values or
-1if none exists
#include <bits/stdc++.h>
using namespace std;
// function to get the next least greater index for each and
// every temp.second of the temp array using stack this
// function is similar to the Next Greater element for each
// and every element of an array using stack difference is
// we are finding the next greater index not value and the
// indexes are stored in the temp[i].second for all i
vector<int> nextGreaterIndex(vector<pair<int, int> >& temp)
{
int n = temp.size();
// initially result[i] for all i is -1
vector<int> res(n, -1);
stack<int> stack;
for (int i = 0; i < n; i++) {
// if the stack is empty or this index is smaller
// than the index stored at top of the stack then we
// push this index to the stack
if (stack.empty() || temp[i].second < stack.top())
stack.push(
temp[i].second); // notice temp[i].second is
// the index
// else this index (i.e. temp[i].second) is greater
// than the index stored at top of the stack we pop
// all the indexes stored at stack's top and for all
// these indexes we make this index i.e.
// temp[i].second as their next greater index
else {
while (!stack.empty()
&& temp[i].second > stack.top()) {
res[stack.top()] = temp[i].second;
stack.pop();
}
// after that push the current index to the
// stack
stack.push(temp[i].second);
}
}
// now res will store the next least greater indexes for
// each and every indexes stored at temp[i].second for
// all i
return res;
}
// now we will be using above function for finding the next
// greater index for each and every indexes stored at
// temp[i].second
vector<int> findLeastGreater(vector<int>& arr)
{
int n = arr.size();
// first of all in temp we store the pairs of {arr[i].i}
vector<pair<int, int> > temp;
for (int i = 0; i < n; i++) {
temp.push_back({ arr[i], i });
}
// we sort the temp according to the first of the pair
// i.e value
sort(temp.begin(), temp.end(),
[](const pair<int, int>& a,
const pair<int, int>& b) {
if (a.first == b.first)
return a.second > b.second;
return a.first < b.first;
});
// now indexes vector will store the next greater index
// for each temp[i].second index
vector<int> indexes = nextGreaterIndex(temp);
// we initialize a result vector with all -1
vector<int> res(n, -1);
for (int i = 0; i < n; i++) {
// now if there is no next greater index after the
// index temp[i].second the result will be -1
// otherwise the result will be the element of the
// array arr at index indexes[temp[i].second]
if (indexes[temp[i].second] != -1)
res[temp[i].second]
= arr[indexes[temp[i].second]];
}
// return the res which will store the least greater
// element of each and every element in the array at its
// right side
return res;
}
// driver code
int main()
{
vector<int> arr = { 8, 58, 71, 18, 31, 32, 63, 92,
43, 3, 91, 93, 25, 80, 28 };
auto res = findLeastGreater(arr);
for (int i : res)
cout << i << ' ';
cout << endl;
return 0;
}
import java.util.*;
class GFG {
// function to get the next least greater index for each and
// every temp.second of the temp array using stack this
// function is similar to the Next Greater element for each
// and every element of an array using stack difference is
// we are finding the next greater index not value and the
// indexes are stored in the temp[i].second for all i
static int[] nextGreaterIndex(List<int[]> temp)
{
int n = temp.size();
// initially result[i] for all i is -1
int[] res = new int[n];
Arrays.fill(res, -1);
Stack<Integer> stack = new Stack<>();
for (int i = 0; i < n; i++) {
if (stack.isEmpty() || temp.get(i)[1] < stack.peek())
stack.push(temp.get(i)[1]);
else {
while (!stack.isEmpty() && temp.get(i)[1] > stack.peek()) {
res[stack.peek()] = temp.get(i)[1];
stack.pop();
}
stack.push(temp.get(i)[1]);
}
}
return res;
}
// now we will be using above function for finding the next
// greater index for each and every indexes stored at
// temp[i].second
static int[] findLeastGreater(int[] arr)
{
int n = arr.length;
// first of all in temp we store the pairs of {arr[i], i}
List<int[]> temp = new ArrayList<>();
for (int i = 0; i < n; i++) {
temp.add(new int[]{arr[i], i});
}
// we sort the temp according to the first of the pair
// i.e value
Collections.sort(temp, (a, b) -> {
if (a[0] == b[0])
return b[1] - a[1];
return a[0] - b[0];
});
int[] indexes = nextGreaterIndex(temp);
int[] res = new int[n];
Arrays.fill(res, -1);
for (int i = 0; i < n; i++) {
if (indexes[temp.get(i)[1]] != -1)
res[temp.get(i)[1]] = arr[indexes[temp.get(i)[1]]];
}
return res;
}
// driver code
public static void main(String[] args)
{
int[] arr = {8, 58, 71, 18, 31, 32, 63, 92,
43, 3, 91, 93, 25, 80, 28};
int[] res = findLeastGreater(arr);
for (int x : res)
System.out.print(x + " ");
}
}
# function to get the next least greater index
def nextGreaterIndex(temp):
n = len(temp)
res = [-1] * n
stack = []
for i in range(n):
if not stack or temp[i][1] < stack[-1]:
stack.append(temp[i][1])
else:
while stack and temp[i][1] > stack[-1]:
res[stack[-1]] = temp[i][1]
stack.pop()
stack.append(temp[i][1])
return res
# now we will be using above function
def findLeastGreater(arr):
n = len(arr)
# first of all in temp we store the pairs
temp = [(arr[i], i) for i in range(n)]
# sort by value, and for equal value by decreasing index
temp.sort(key=lambda x: (x[0], -x[1]))
indexes = nextGreaterIndex(temp)
res = [-1] * n
for i in range(n):
if indexes[temp[i][1]] != -1:
res[temp[i][1]] = arr[indexes[temp[i][1]]]
return res
# driver code
arr = [8, 58, 71, 18, 31, 32, 63, 92,
43, 3, 91, 93, 25, 80, 28]
res = findLeastGreater(arr)
print(*res)
using System;
using System.Collections.Generic;
class GFG {
static int[] nextGreaterIndex(List<int[]> temp)
{
int n = temp.Count;
int[] res = new int[n];
for (int i = 0; i < n; i++) res[i] = -1;
Stack<int> stack = new Stack<int>();
for (int i = 0; i < n; i++) {
if (stack.Count == 0 || temp[i][1] < stack.Peek())
stack.Push(temp[i][1]);
else {
while (stack.Count > 0 && temp[i][1] > stack.Peek()) {
res[stack.Peek()] = temp[i][1];
stack.Pop();
}
stack.Push(temp[i][1]);
}
}
return res;
}
static int[] findLeastGreater(int[] arr)
{
int n = arr.Length;
List<int[]> temp = new List<int[]>();
for (int i = 0; i < n; i++) {
temp.Add(new int[] {arr[i], i});
}
temp.Sort((a, b) => {
if (a[0] == b[0])
return b[1].CompareTo(a[1]);
return a[0].CompareTo(b[0]);
});
int[] indexes = nextGreaterIndex(temp);
int[] res = new int[n];
for (int i = 0; i < n; i++) res[i] = -1;
for (int i = 0; i < n; i++) {
if (indexes[temp[i][1]] != -1)
res[temp[i][1]] = arr[indexes[temp[i][1]]];
}
return res;
}
public static void Main()
{
int[] arr = {8, 58, 71, 18, 31, 32, 63, 92,
43, 3, 91, 93, 25, 80, 28};
int[] res = findLeastGreater(arr);
foreach (int x in res)
Console.Write(x + " ");
}
}
// function to get the next least greater index
function nextGreaterIndex(temp) {
let n = temp.length;
let res = new Array(n).fill(-1);
let stack = [];
for (let i = 0; i < n; i++) {
if (stack.length === 0 || temp[i][1] < stack[stack.length - 1])
stack.push(temp[i][1]);
else {
while (stack.length && temp[i][1] > stack[stack.length - 1]) {
res[stack[stack.length - 1]] = temp[i][1];
stack.pop();
}
stack.push(temp[i][1]);
}
}
return res;
}
// now we will be using above function
function findLeastGreater(arr) {
let n = arr.length;
let temp = [];
for (let i = 0; i < n; i++) {
temp.push([arr[i], i]);
}
temp.sort((a, b) => {
if (a[0] === b[0]) return b[1] - a[1];
return a[0] - b[0];
});
let indexes = nextGreaterIndex(temp);
let res = new Array(n).fill(-1);
for (let i = 0; i < n; i++) {
if (indexes[temp[i][1]] !== -1)
res[temp[i][1]] = arr[indexes[temp[i][1]]];
}
return res;
}
// driver code
let arr = [8, 58, 71, 18, 31, 32, 63, 92,
43, 3, 91, 93, 25, 80, 28];
let res = findLeastGreater(arr);
console.log(...res);
Output
18 63 80 25 32 43 80 93 80 25 93 -1 28 -1 -1