Next Greater Element
Difficulty: Easy
Problem
You get two distinct 0-indexed integer arrays, nums1 and nums2, where every value of nums1 also appears in nums2. For each value x in nums1, look at its position in nums2 and move rightwards to find the first value strictly larger than x; that is its next greater element. If nothing larger lies to the right, the answer for x is -1. Return the answers in the order of nums1.
Example
Input: nums1 = [4, 1, 2], nums2 = [1, 3, 4, 2]
Output: [-1, 3, -1]
Explanation: For 4 in nums2 = [1, 3, 4, 2]: only 2 lies to its right and 2 < 4, so the answer is -1. For 1: the value right after it is 3 > 1, so the answer is 3. For 2: it is the last element, so nothing is to its right and the answer is -1.
Brute-force approach
For each element in nums1, find it in nums2, then scan rightward in nums2 for the first greater element.
Steps
- For each element x in nums1:
- Find x's index in nums2
- Scan from that index to the right for first element > x
- If found, record it; otherwise record -1
Time complexity: O(m × n) · Space complexity: O(1)
Trade-offs
- For each of m elements in nums1, we may scan up to n elements in nums2
- Redundant: we may re-scan the same portion of nums2 for different queries
- O(m × n) is too slow for large inputs
Optimal approach
Key insight: As we traverse nums2, elements waiting for their 'next greater' sit in a decreasing stack. A new larger element resolves all of them at once.
Process nums2 with a monotonic decreasing stack. For each element, pop all smaller stack elements (they found their next greater). Store results in a hash map for O(1) lookup.
Steps
- Initialize an empty stack and a hash map
- For each num in nums2:
- While stack is not empty and stack.top < num: pop and record map[popped] = num
- Push num onto the stack
- For each num in nums1: result = map[num] or -1
Time complexity: O(n + m) · Space complexity: O(n)
Pseudocode
function nextGreaterElement(nums1, nums2):
map = {}
stack = []
for num in nums2:
while stack not empty and stack.top < num:
map[stack.pop()] = num
stack.push(num)
result = []
for num in nums1:
result.push(map[num] or -1)
return result
Hints
- Use a monotonic decreasing stack to find next greater elements efficiently
- When a larger element appears, it is the 'next greater' for all smaller elements currently on the stack
- Use a hash map to store each element's next greater element for O(1) lookup
Complexity questions
What is the time complexity of the brute force approach?
O(m × n). For each of m elements in nums1, we may scan up to n elements in nums2 → O(m × n).
What is the time complexity of the monotonic stack approach?
O(m + n). We process nums2 once with the stack in O(n). Each element is pushed/popped at most once. Then we look up m elements in O(m). Total: O(n + m).
What is the space complexity of the monotonic stack approach?
O(n). The hash map and stack can each hold up to n elements from nums2 → O(n) space.
Check your understanding of Next Greater Element
What does 'next greater element' mean for a number in nums2?
The first element to the right that is greater than it. The next greater element is the first element scanning rightward from the number's position that has a larger value.
For nums2 = [1, 3, 4, 2], what is the next greater element for 4?
-1 (no greater element to its right). Looking right from 4 in [1, 3, 4, 2]: only 2 remains, and 2 < 4. There is no element greater than 4 to its right, so the answer is -1.
For nums2 = [1, 3, 4, 2], what is the next greater element for 3?
4. Looking right from 3 in [1, 3, 4, 2]: the first element greater than 3 is 4.
Related problems
- Daily Temperatures (Medium)
- Largest Rectangle in Histogram (Hard)