#496 Next Greater Element I
the problem
In plain words
nums1 is a subset of nums2 (all values distinct). For each x in nums1, find the first number to the right of x in nums2 that is greater than x, or −1 if none.
in nums1 = [4,1,2], nums2 = [1,3,4,2]
out [-1,3,-1]
in nums1 = [2,4], nums2 = [1,2,3,4]
out [3,-1]
- 1 ≤ nums1.length ≤ nums2.length ≤ 1000
- 0 ≤ values ≤ 10⁴, all distinct
- Follow-up: O(nums1.length + nums2.length)
your turn
Try it before you peek
Read the examples, say the brute force out loud, then write code: here or on LeetCode ↗. Stuck for 20 minutes? Open one hint at a time.
Solve it in the browser
LeetCode-style: complete the class. Compiled by the real javac (Java 17) and judged right here — nothing is sent anywhere.
Solutions are hidden so you can try first. Even 20 minutes of real effort makes the answer stick far better than reading it.
Marking the problem solved, or opening every hint, also shows it.
the aha
Key insight
patternMonotonic stackHash lookup (seen before?)
Answer the question once for every value in nums2 with a monotonic stack, store it in a map, then each nums1 query is a lookup.
solutions
From brute force to optimal
For each query, locate it in nums2 and scan to its right.
- For each x in nums1: find its index j in nums2.
- Scan nums2[j+1..] for the first value > x.
m queries, each scanning up to n elements of nums2.
Only the output.
class Solution { public int[] nextGreaterElement(int[] nums1, int[] nums2) { int[] ans = new int[nums1.length]; for (int i = 0; i < nums1.length; i++) { int j = 0; while (nums2[j] != nums1[i]) j++; // find it in nums2 ans[i] = -1; for (int k = j + 1; k < nums2.length; k++) { // scan right for something bigger if (nums2[k] > nums1[i]) { ans[i] = nums2[k]; break; } } } return ans; }}One pass over nums2 fills value → next greater. Distinct values make the value a safe key.
- For each x in nums2: while stack top < x, map[pop()] = x. Push x.
- For each query: map.getOrDefault(x, −1).
Each nums2 value is pushed and popped at most once; each query is an O(1) average map lookup.
The map and the stack.
class Solution { public int[] nextGreaterElement(int[] nums1, int[] nums2) { Map<Integer, Integer> nextGreater = new HashMap<>(); // value -> its next greater value Deque<Integer> stack = new ArrayDeque<>(); // values waiting for an answer for (int x : nums2) { while (!stack.isEmpty() && stack.peek() < x) { nextGreater.put(stack.pop(), x); } stack.push(x); } int[] ans = new int[nums1.length]; for (int i = 0; i < nums1.length; i++) { ans[i] = nextGreater.getOrDefault(nums1[i], -1); } return ans; }}The stack part, step by step
in the room
How to say it in the interview
talk track
- Notice the subset structure: "I'll precompute answers for all of nums2, then look up the queries."
- Point out that pushing values (not indices) is fine here because values are distinct and we only need the value.
traps
- Looking for the next greater value in nums1 — the search happens in nums2.
map.get(x)for a value that was never popped returnsnull, and unboxing it into anintthrows. UsegetOrDefault(x, -1).- Using
Stackinstead ofArrayDeque— it works, butStackis synchronized and slower.
what they ask next
Follow-ups
What if values could repeat?
Store answers by index (int[] for nums2) and map each query to its index — or answer queries by position directly.
before you submit
Edge cases to test
- The biggest value never gets an answer: −1.
- The answer can be far away: in [9, 5, 0, 7], the next greater of 5 is 7, not 0.
- A falling nums2 gives −1 for every query.
practise next
Similar problems
- #739Daily TemperaturesMediumin Stacks
- #84Largest Rectangle in HistogramHardin Stacks