Next Greater Element II
For each element in a circular array, find the next greater element, searching wrap-around; return -1 where none exists.
- 1 <= nums.length <= 10⁴
- -10⁹ <= nums[i] <= 10⁹
Intuition
Next greater element ii finds, for each element, the next larger value to its right — but the array is circular, so the search wraps past the end back to the beginning.
The non-circular version is a classic monotonic decreasing stack: walk the array holding indices whose next greater element is still unknown, and when a larger value arrives, it resolves every smaller index waiting on the stack.
The circularity needs one adjustment, and there is a clean way to get it:
- Iterate 2n times using i % n to index, which simulates walking the array twice without allocating a doubled copy.
One full pass leaves some indices unresolved; the second pass lets values from the array's start resolve them. Anything still on the stack after both passes genuinely has no greater element anywhere, and stays −1.
Actually concatenating the array to itself also works and is easier to picture, but doubles the memory for no benefit.
One detail matters in the second pass: do not push indices during it. Every index was already pushed in the first pass, and pushing again creates duplicates that overwrite correct answers. The second pass only pops.
The result array must be initialised to −1 so unresolved indices carry the right default without a final cleanup pass.
The stack holds indices rather than values, since the answer must be written back to the correct position.
Each index is pushed and popped at most once across both passes, so the cost stays O(n) despite the doubled loop.
The circular version of next-greater. Walking 2n - 1 down to 0 with i % n simulates two laps, so every element sees the wrap-around; results are only recorded on the second lap, when the stack already holds everything to the right.
Approach
Before reading on: price up what the direct approach costs here, then ask what ordering you can maintain so the answer is always at one end. Aim for O(n) time and O(n) space.
Use a monotonic decreasing stack
Hold indices whose next greater element is still unknown. A larger arriving value resolves every smaller index waiting, which is what makes one pass sufficient.
Simulate the wrap with modulo
Iterate 2n times indexing with i % n. This walks the array twice without allocating a doubled copy, letting early values resolve late indices.
Store indices, not values
The answer must be written to the correct position, so the stack holds indices. Values alone lose track of where each result belongs.
Do not push in the second pass
Every index was pushed during the first pass. Pushing again creates duplicates that overwrite correct answers — the second pass only pops.
Initialise results to -1
Indices never resolved keep the -1 default, which is exactly the required answer for elements with no greater value anywhere.
Cost of the approach
Each index is pushed and popped at most once across both passes, giving O(n) time and O(n) space despite the doubled loop.
Solution & live demo
Common pitfalls
Recording results on both laps
if st: res[i % n] = st[-1]
if i < n and st:
res[i] = st[-1]During the first (higher-index) lap the stack hasn't yet seen the wrapped elements, so the answers are incomplete. The extra lap exists only to prime the stack; writes must wait until i is a real index.
Popping on strict greater-than
while st and st[-1] < cur:
while st and st[-1] <= cur:
"Next greater" is strict, so an equal value is not an answer and must be discarded. Keeping equals makes the stack report a same-valued element as the next greater one.
Doubling the array instead
nums = nums + nums
cur = nums[i % n]
Functionally the same but allocates a second array. The modulo indexing gets the identical traversal with no extra space, which matters when the array is large.
Edge cases
Strict > means nothing qualifies, so every answer is -1.
The maximum gets -1 and everything else points to its right neighbour.
It cannot exceed itself, so the answer is [-1].
Always -1, since nothing anywhere in the circle is greater.