18. Next Greater Element in Circular Array
β GFG solution to the Next Greater Element in Circular Array problem: find next greater element for each position in circular array using monotonic stack technique. π
The problem can be found at the following link: π Question Link
π§© Problem Description
Given a circular integer array arr[]
, the task is to determine the next greater element (NGE) for each element in the array.
The next greater element of an element arr[i]
is the first element that is greater than arr[i]
when traversing circularly. If no such element exists, return -1 for that position.
Note: Since the array is circular, after reaching the last element, the search continues from the beginning until we have looked at all elements once.
π Examples
Example 1
Input: arr[] = [1, 3, 2, 4]
Output: [3, 4, 4, -1]
Explanation:
The next greater element for 1 is 3.
The next greater element for 3 is 4.
The next greater element for 2 is 4.
The next greater element for 4 does not exist, so return -1.
Example 2
Input: arr[] = [0, 2, 3, 1, 1]
Output: [2, 3, -1, 2, 2]
Explanation:
The next greater element for 0 is 2.
The next greater element for 2 is 3.
The next greater element for 3 does not exist, so return -1.
The next greater element for 1 is 2 (from circular traversal).
The next greater element for 1 is 2 (from circular traversal).
π Constraints
$1 \le \text{arr.size()} \le 10^5$
$0 \le \text{arr}[i] \le 10^6$
β
My Approach
The optimal approach uses a Monotonic Stack technique with circular array simulation to efficiently find the next greater element:
Monotonic Stack + Circular Traversal
Initialize Variables:
Use a stack to store indices of elements for which we haven't found the next greater element yet.
Create a result vector initialized with -1 for all positions.
Traverse the array twice (2*n iterations) to simulate circular behavior.
Stack Operations:
For each element, pop from stack all indices whose corresponding values are smaller than current element.
Set the next greater element for these popped indices as the current element.
Push current index to stack only in the first traversal (i < n).
Circular Logic:
Use modular arithmetic
i % n
to access array elements in circular manner.The second traversal handles cases where next greater element is at the beginning of array.
Monotonic Property:
Stack maintains indices in decreasing order of their corresponding values.
This ensures O(1) amortized time for finding next greater elements.
π Time and Auxiliary Space Complexity
Expected Time Complexity: O(n), where n is the size of the array. Each element is pushed and popped from the stack at most once, resulting in O(2n) operations which simplifies to O(n).
Expected Auxiliary Space Complexity: O(n), where n is the size of the array. In the worst case (when array is in decreasing order), all indices are stored in the stack simultaneously.
π§βπ» Code (C++)
class Solution {
public:
vector<int> nextGreater(vector<int> &arr) {
int n = arr.size();
vector<int> res(n, -1);
stack<int> stk;
for (int i = 0; i < 2 * n; i++) {
while (!stk.empty() && arr[stk.top()] < arr[i % n]) {
res[stk.top()] = arr[i % n];
stk.pop();
}
if (i < n) stk.push(i);
}
return res;
}
};
β Code (Java)
class Solution {
public ArrayList<Integer> nextGreater(int[] arr) {
int n = arr.length;
ArrayList<Integer> res = new ArrayList<>(Collections.nCopies(n, -1));
Stack<Integer> stk = new Stack<>();
for (int i = 0; i < 2 * n; i++) {
while (!stk.isEmpty() && arr[stk.peek()] < arr[i % n]) {
res.set(stk.pop(), arr[i % n]);
}
if (i < n) stk.push(i);
}
return res;
}
}
π Code (Python)
class Solution:
def nextGreater(self, arr):
n = len(arr)
res = [-1] * n
stk = []
for i in range(2 * n):
while stk and arr[stk[-1]] < arr[i % n]:
res[stk.pop()] = arr[i % n]
if i < n:
stk.append(i)
return res
π§ Contribution and Support
For discussions, questions, or doubts related to this solution, feel free to connect on LinkedIn: π¬ Any Questions?. Let's make this learning journey more collaborative!
β If you find this helpful, please give this repository a star! β
πVisitor Count
Last updated