Find the next greater element in a Circular Array
Given a circular array arr[] of N integers such that the last element of the given array is adjacent to the first element of the array, the task is to print the Next Greater Element in this circular array. Elements for which no greater element exist, consider the next greater element as “-1”.
Examples:
Input: arr[] = {5, 6, 7}
Output: {6, 7, -1}
Explanation:
Next Greater Element for 5 is 6, for 6 is 7, and for 7 is -1 as we don’t have any element greater than itself so its -1.
Input: arr[] = {4, -2, 5, 8}
Output: {5, 5, 8, -1}
Explanation:
Next Greater Element for 4 is 5, for -2 its 5, for 5 is 8, and for 8 is -1 as we don’t have any element greater than itself so its -1, and for 3 its 4.
Approach: This problem can be solved using Greedy Approach. Below are the steps:
- For the property of the circular array to be valid append the given array elements to the same array once again.
For Example:
Let arr[] = {1, 4, 3}
After appending the same set of elements arr[] becomes
arr[] = {1, 4, 3, 1, 4, 3}
- Find the next greater element till N elements in the above array formed.
- If any greater element is found then print that element, else print “-1”.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
void printNGE( int A[], int n)
{
int arr[2 * n];
for ( int i = 0; i < 2 * n; i++)
arr[i] = A[i % n];
int next, i, j;
for (i = 0; i < n; i++) {
next = -1;
for (j = i + 1; j < 2 * n; j++) {
if (arr[i] < arr[j]) {
next = arr[j];
break ;
}
}
cout << next << ", " ;
}
}
int main()
{
int arr[] = { 1, 2, 1 };
int N = sizeof (arr) / sizeof (arr[0]);
printNGE(arr, N);
return 0;
}
|
C
#include <stdio.h>
void printNGE( int A[], int n)
{
int arr[2 * n];
for ( int i = 0; i < 2 * n; i++)
arr[i] = A[i % n];
int next, i, j;
for (i = 0; i < n; i++) {
next = -1;
for (j = i + 1; j < 2 * n; j++) {
if (arr[i] < arr[j]) {
next = arr[j];
break ;
}
}
printf ( "%d, " ,next);
}
}
int main()
{
int arr[] = { 1, 2, 1 };
int N = sizeof (arr) / sizeof (arr[0]);
printNGE(arr, N);
return 0;
}
|
Java
import java.util.*;
class GFG {
static void printNGE( int [] A, int n)
{
int [] arr = new int [ 2 * n];
for ( int i = 0 ; i < 2 * n; i++)
arr[i] = A[i % n];
int next;
for ( int i = 0 ; i < n; i++) {
next = - 1 ;
for ( int j = i + 1 ; j < 2 * n; j++) {
if (arr[i] < arr[j]) {
next = arr[j];
break ;
}
}
System.out.print(next + ", " );
}
}
public static void main(String args[])
{
int [] arr = { 1 , 2 , 1 };
int N = arr.length;
printNGE(arr, N);
}
}
|
Python3
def printNGE(A, n):
arr = [ 0 ] * ( 2 * n)
for i in range ( 2 * n):
arr[i] = A[i % n]
for i in range (n):
next = - 1
for j in range (i + 1 , 2 * n):
if (arr[i] < arr[j]):
next = arr[j]
break
print ( next , end = ", " )
if __name__ = = '__main__' :
arr = [ 1 , 2 , 1 ]
N = len (arr)
printNGE(arr, N)
|
C#
using System;
class GFG{
static void printNGE( int []A, int n)
{
int []arr = new int [2 * n];
for ( int i = 0; i < 2 * n; i++)
arr[i] = A[i % n];
int next;
for ( int i = 0; i < n; i++)
{
next = -1;
for ( int j = i + 1; j < 2 * n; j++)
{
if (arr[i] < arr[j])
{
next = arr[j];
break ;
}
}
Console.Write(next + ", " );
}
}
public static void Main()
{
int []arr = { 1, 2, 1 };
int N = arr.Length;
printNGE(arr, N);
}
}
|
Javascript
<script>
function printNGE(A, n)
{
let arr = Array.from({length: 2 * n}, (_, i) => 0);
for (let i = 0; i < 2 * n; i++)
arr[i] = A[i % n];
let next;
for (let i = 0; i < n; i++)
{
next = -1;
for (let j = i + 1; j < 2 * n; j++)
{
if (arr[i] < arr[j])
{
next = arr[j];
break ;
}
}
document.write(next + ", " );
}
}
let arr = [ 1, 2, 1 ];
let N = arr.length;
printNGE(arr, N);
</script>
|
This approach takes of O(n2) time but takes extra space of order O(n)
A space-efficient solution is to deal with circular arrays using the same array. If a careful observation is run through the array, then after the n-th index, the next index always starts from 0 so using the mod operator, we can easily access the elements of the circular list, if we use (i)%n and run the loop from i-th index to n+i-th index, and apply mod we can do the traversal in a circular array within the given array without using any extra space.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
void printNGE( int A[], int n)
{
int k;
for ( int i = 0; i < n; i++)
{
k = -1;
for ( int j = i + 1; j < n + i; j++)
{
if (A[i] < A[j % n])
{
cout << " " << A[j % n];
k = 1;
break ;
}
}
if (k == -1)
cout << "-1 " ;
}
}
int main()
{
int arr[] = { 8, 6, 7 };
int N = sizeof (arr) / sizeof (arr[0]);
printNGE(arr, N);
return 0;
}
|
C
#include <stdio.h>
void printNGE( int A[], int n)
{
int k;
for ( int i = 0; i < n; i++) {
k = -1;
for ( int j = i + 1; j < n + i; j++) {
if (A[i] < A[j % n]) {
printf ( "%d " , A[j % n]);
k = 1;
break ;
}
}
if (k == -1)
printf ( "-1 " );
}
}
int main()
{
int arr[] = { 8, 6, 7 };
int N = sizeof (arr) / sizeof (arr[0]);
printNGE(arr, N);
return 0;
}
|
Java
import java.io.*;
class GFG {
static void printNGE( int A[], int n)
{
int k;
for ( int i = 0 ; i < n; i++) {
k = - 1 ;
for ( int j = i + 1 ; j < n + i; j++) {
if (A[i] < A[j % n]) {
System.out.print(A[j % n] + " " );
k = 1 ;
break ;
}
}
if (k == - 1 )
System.out.print( "-1 " );
}
}
public static void main(String[] args)
{
int [] arr = { 8 , 6 , 7 };
int N = arr.length;
printNGE(arr, N);
}
}
|
Python3
def printNGE(A, n) :
for i in range (n) :
k = - 1
for j in range (i + 1 , n + i) :
if (A[i] < A[j % n]) :
print (A[j % n], end = " " )
k = 1
break
if (k = = - 1 ) :
print ( "-1 " , end = "")
arr = [ 8 , 6 , 7 ]
N = len (arr)
printNGE(arr, N)
|
C#
using System;
class GFG {
static void printNGE( int [] A, int n)
{
int k;
for ( int i = 0; i < n; i++)
{
k = -1;
for ( int j = i + 1; j < n + i; j++)
{
if (A[i] < A[j % n])
{
Console.Write(A[j % n] + " " );
k = 1;
break ;
}
}
if (k == -1)
Console.Write( "-1 " );
}
}
static void Main()
{
int [] arr = { 8, 6, 7 };
int N = arr.Length;
printNGE(arr, N);
}
}
|
Javascript
<script>
function printNGE(A, n)
{
let k;
for (let i = 0; i < n; i++)
{
k = -1;
for (let j = i + 1; j < n + i; j++)
{
if (A[i] < A[j % n])
{
document.write(A[j % n] + " " );
k = 1;
break ;
}
}
if (k == -1)
document.write( "-1 " );
}
}
let arr = [ 8, 6, 7 ];
let N = arr.length;
printNGE(arr, N);
</script>
|
Time Complexity: O(n2)
Auxiliary Space: O(1)
Method 3rd: The method uses the same concept used in method 2 for circular Array but uses Stack to find out the next greater element in O(n) time complexity where n is the size of the array. For better understanding, you can see the next greater element.
C++
#include <bits/stdc++.h>
using namespace std;
void printNGE( int a[], int n)
{
stack< int > s;
vector< int > ans(n);
for ( int i = 2 * n - 1; i >= 0; i--) {
while (!s.empty() && a[i % n] >= s.top())
s.pop();
if (i < n) {
if (!s.empty())
ans[i] = s.top();
else
ans[i] = -1;
}
s.push(a[i % n]);
}
for ( int i = 0; i < n; i++)
cout << ans[i] << " " ;
}
int main()
{
int arr[] = { 8, 6, 7 };
int N = sizeof (arr) / sizeof (arr[0]);
printNGE(arr, N);
return 0;
}
|
Java
import java.io.*;
import java.util.*;
class GFG {
public static void printNGE( int [] arr)
{
Stack<Integer> stack = new Stack<>();
int n = arr.length;
int [] result = new int [n];
for ( int i = 2 *n - 1 ; i >= 0 ; i--)
{
while (!stack.isEmpty() && arr[i % n] >= stack.peek()){
stack.pop();
}
if (i < n)
{
if (!stack.isEmpty())
result[i] = stack.peek();
else
result[i] = - 1 ;
}
stack.push(arr[i % n]);
}
for ( int i:result)
{
System.out.print(i + " " );
}
}
public static void main (String[] args) {
int [] arr = { 8 , 6 , 7 };
printNGE(arr);
}
}
|
Python3
def printNGE(a, n):
s = []
ans = [ 0 ] * n
for i in range ( 2 * n - 1 , - 1 , - 1 ):
while s and a[i % n] > = s[ - 1 ]:
s.pop()
if i < n:
if s:
ans[i] = s[ - 1 ]
else :
ans[i] = - 1
s.append(a[i % n])
for i in range (n):
print (ans[i], end = " " )
if __name__ = = "__main__" :
arr = [ 8 , 6 , 7 ]
N = len (arr)
printNGE(arr, N)
|
C#
using System;
using System.Collections;
public class GFG {
static void printNGE( int [] arr)
{
Stack stack = new Stack();
int n = arr.Length;
int [] result = new int [n];
for ( int i = 2 * n - 1; i >= 0; i--) {
while (stack.Count != 0
&& arr[i % n] >= ( int )stack.Peek()) {
stack.Pop();
}
if (i < n) {
if (stack.Count != 0) {
result[i] = ( int )stack.Peek();
}
else {
result[i] = -1;
}
}
stack.Push(arr[i % n]);
}
foreach ( int i in result) { Console.Write(i + " " ); }
}
static public void Main()
{
int [] arr = { 8, 6, 7 };
printNGE(arr);
}
}
|
Javascript
<script>
function printNGE(a, n){
let s = []
let ans = new Array(n).fill(0)
for (let i=2 * n - 1;i>=0;i--){
while (s.length>0 && a[i % n] >= s[s.length - 1])
s.pop()
if (i < n){
if (s.length>0)
ans[i] = s[s.length-1]
else
ans[i] = -1
}
s.push(a[i % n])
}
for (let i=0;i<n;i++){
document.write(ans[i], " " )
}
}
let arr = [8, 6, 7]
let N = arr.length
printNGE(arr, N)
</script>
|
Time Complexity: O(N)
Auxiliary Space: O(N)
Method :- 4
In method 3, next greater element is calculated by traversing the array from backward (end) but we can also do the same in forward (start) traversal.
C++
#include <bits/stdc++.h>
using namespace std;
void printNGE( int nums[], int n)
{
vector< int > ans(n, -1);
stack< int > s;
for ( int i = 0; i < 2 * n; i++) {
while (!s.empty() && nums[s.top()] < nums[i % n]) {
ans[s.top()] = nums[i % n];
s.pop();
}
if (i < n)
s.push(i);
}
for ( auto it : ans)
cout << it << " " ;
}
int main()
{
int arr[] = { 8, 6, 7 };
int N = sizeof (arr) / sizeof (arr[0]);
printNGE(arr, N);
return 0;
}
|
Java
import java.io.*;
import java.util.*;
class GFG {
public static void printNGE( int [] arr)
{
Stack<Integer> stack = new Stack<>();
int n = arr.length;
int [] result = new int [n];
Arrays.fill(result,- 1 );
for ( int i = 0 ; i < 2 *n- 1 ; i++)
{
while (!stack.isEmpty() && arr[i % n] > arr[stack.peek()]){
result[stack.peek()] = arr[i%n];
stack.pop();
}
if (i < n)
stack.push(i);
}
for ( int i:result)
{
System.out.print(i + " " );
}
}
public static void main (String[] args) {
int [] arr = { 8 , 6 , 7 };
printNGE(arr);
}
}
|
Python3
def printNGE(arr):
stack = []
n = len (arr)
result = [ - 1 ] * n
for i in range ( 2 * n - 1 ):
while stack and arr[i % n] > arr[stack[ - 1 ]]:
result[stack[ - 1 ]] = arr[i % n]
stack.pop()
if i < n:
stack.append(i)
for i in result:
print (i, end = ' ' )
arr = [ 8 , 6 , 7 ]
printNGE(arr)
|
C#
using System;
using System.Collections;
using System.Collections.Generic;
public class GFG {
static void printNGE( int [] arr)
{
Stack stack = new Stack();
int n = arr.Length;
int [] result = new int [n];
Array.Fill(result, -1);
for ( int i = 0; i < 2 * n - 1; i++) {
while (stack.Count != 0
&& arr[i % n] > arr[( int )stack.Peek()]) {
result[( int )stack.Peek()] = arr[i % n];
stack.Pop();
}
if (i < n)
stack.Push(i);
}
foreach ( int i in result) { Console.Write(i + " " ); }
}
static public void Main()
{
int [] arr = { 8, 6, 7 };
printNGE(arr);
}
}
|
Javascript
<script>
function printNGE(nums, n)
{
let ans = new Array(n).fill(-1);
let s = [];
for (let i = 0; i < 2 * n; i++) {
while (s.length > 0 && nums[s[s.length - 1]] < nums[i % n]) {
ans[s[s.length - 1]] = nums[i % n];
s.pop();
}
if (i < n)
s.push(i);
}
for (let it of ans)
document.write(it , " " );
}
let arr = [ 8, 6, 7 ];
let N = arr.length;
printNGE(arr, N);
</script>
|
Time Complexity: O(N)
Auxiliary Space: O(N)
Method 5: (Using Deque)
Intuition:
We can use a stack to find the next greater element of each element in the given array. We loop through the array twice to compare each element with every other element. For each element, we push its index onto the stack. If the current element is greater than the top element of the stack, we pop the stack and update the result array with the current element for the popped index. We continue this process until the stack is empty or the top element of the stack is greater than or equal to the current element. Finally, we return the result array.
C++
#include <bits/stdc++.h>
using namespace std;
void printNGE(vector< int >& nums,vector< int > &ret)
{
deque< int > dq;
for ( int i = 1; i < nums.size(); i++)
dq.push_back(nums[i]);
for ( int i = 0; i < nums.size(); i++)
{
int n = ret.size();
for ( int j = 0; j < dq.size(); j++)
{
if (dq[j] > nums[i])
{
ret.emplace_back(dq[j]);
break ;
}
}
if (ret.size() == n)
ret.emplace_back(-1);
dq.pop_front();
dq.push_back(nums[i]);
}
}
int main()
{
vector< int > arr{ 8, 6, 7 };
vector< int > res;
printNGE(arr,res);
for ( int i=0;i<res.size();i++){
cout<<res[i]<< " " ;
}
return 0;
}
|
Java
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Deque;
import java.util.List;
class GFG {
public static void printNGE(List<Integer> nums, List<Integer> ret) {
Deque<Integer> dq = new ArrayDeque<>();
for ( int i = 1 ; i < nums.size(); i++) {
dq.add(nums.get(i));
}
for ( int i = 0 ; i < nums.size(); i++) {
int n = ret.size();
for ( int j = 0 ; j < dq.size(); j++) {
if (dq.peek() > nums.get(i)) {
ret.add(dq.peek());
break ;
}
dq.add(dq.poll());
}
if (ret.size() == n) {
ret.add(- 1 );
}
dq.pollFirst();
dq.add(nums.get(i));
}
}
public static void main(String[] args) {
List<Integer> arr = List.of( 8 , 6 , 7 );
List<Integer> res = new ArrayList<>();
printNGE(arr, res);
for ( int i = 0 ; i < res.size(); i++) {
System.out.print(res.get(i) + " " );
}
}
}
|
Python3
from collections import deque
def print_NGE(nums):
ret = []
dq = deque()
for i in range ( 1 , len (nums)):
dq.append(nums[i])
for i in range ( len (nums)):
n = len (ret)
for j in range ( len (dq)):
if dq[j] > nums[i]:
ret.append(dq[j])
break
if len (ret) = = n:
ret.append( - 1 )
dq.popleft()
dq.append(nums[i])
return ret
arr = [ 8 , 6 , 7 ]
res = print_NGE(arr)
for i in range ( len (res)):
print (res[i], end = " " )
|
C#
using System;
using System.Collections.Generic;
public class GFG
{
static void PrintNGE(List< int > nums, List< int > ret)
{
Queue< int > dq = new Queue< int >(nums.GetRange(1, nums.Count - 1));
for ( int i = 0; i < nums.Count; i++)
{
int n = ret.Count;
foreach ( int num in dq)
{
if (num > nums[i])
{
ret.Add(num);
break ;
}
}
if (ret.Count == n)
ret.Add(-1);
dq.Dequeue();
dq.Enqueue(nums[i]);
}
}
public static void Main( string [] args)
{
List< int > arr = new List< int > { 8, 6, 7 };
List< int > res = new List< int >();
PrintNGE(arr, res);
foreach ( int val in res)
{
Console.Write(val + " " );
}
}
}
|
Javascript
function printNGE(nums, ret) {
let dq = [];
for (let i = 1; i < nums.length; i++) {
dq.push(nums[i]);
}
for (let i = 0; i < nums.length; i++) {
let n = ret.length;
for (let j = 0; j < dq.length; j++) {
if (dq[j] > nums[i]) {
ret.push(dq[j]);
break ;
}
}
if (ret.length === n) {
ret.push(-1);
}
dq.shift();
dq.push(nums[i]);
}
}
let arr = [8, 6, 7];
let res = [];
printNGE(arr, res);
for (let i = 0; i < res.length; i++) {
console.log(res[i] + " " );
}
|
Time Complexity:O(n)
Auxiliary Space: O(n)
Last Updated :
02 Nov, 2023
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...