Problem Statement in English
You’re given an array nums of positive integers.
You must find the next greater element for each element in the array, and if it does not exist, output -1. You’re allowed to look through the array in a circular manner. So, the next greater element index $2$ could be at index $0$, if it’s not after index $2$.
Approach
We use the concept of a monotonic stack to solve this problem. Check out this problem to get a better idea of it.
Add to that a second iteration of the array to simulate the circular nature of the array, and we’re done with the problem.
Solution in Python
- Brute force solution
class Solution:
def nextGreaterElements(self, nums: List[int]) -> List[int]:
ans = []
for i in range(len(nums)):
j = i + 1
found = False
l = len(nums)
while j % l != i:
if nums[j % l] > nums[i]:
found = True
ans.append(nums[j % l])
break
else:
j += 1
if not found:
ans.append(-1)
return ans
- Optimized solution
class Solution:
def nextGreaterElements(self, nums: List[int]) -> List[int]:
# store length of nums
l = len(nums)
# initialize answer
ans = [-1] * l
# index, value
stack: list[tuple[int, int]] = []
# iterate over the array twice
# this gives that circular effect
for i in range(len(nums) * 2):
# the modulo index
mi = i % l
# if the stack is not empty
# and the value at the top of the stack
# is less than the current element
while stack and stack[-1][1] < nums[mi]:
# pop the element from the stack
# and update the answer to store
# this number at the correct index
ans[stack.pop()[0]] = nums[mi]
if i < l:
# ensure we only append values once,
# since there's no need to append the same value twice
stack.append((i, nums[i]))
# return the answer
return ans
Complexity
Time: $O(n)$
Since we iterate over $n$ elements at most.Space: $O(n)$
Since we store the answer in a list of size $n$.
Mistakes I Made
I had to think about the circular nature of the array. Had to look that up :(
And we are done.