#496EasyMonotonic stack
Next Greater Element I
Start dumb: search to the right, every time
For each value in nums1, find where it lives in nums2, then walk
right until you hit something bigger. Two nested scans over nums2 —
O(n·m), and worse, most of that walking is repeated: the same stretch
of nums2 gets re-scanned for every query that lands near it.
Find the bottleneck
The waste is that each query rediscovers the same “next bigger number to
the right” from scratch. But that relationship doesn’t depend on nums1
at all — it’s a fixed property of nums2. Compute it once for every
element of nums2, cache it, and the nums1 queries become one lookup
each.
The optimal shape
- For each
numinnums2, while the stack’s top is smaller thannum, pop it —numis that popped value’s next-greater. Record it in avalue → nextGreatermap. - Push
num; it now waits for its own bigger number. - Anything still on the stack at the end never found one — its answer is −1.
- Each
nums1query is a single map lookup (default −1).
In the player, the stack is the highlighted run of nums2; watch one big
number clear a whole backlog of waiters in consecutive steps.
Watch it think
Run the default, then the traps: a lone big number answering a backlog of
three (4,3,2 | 4,3,2,5), a strictly falling nums2 where every answer
is −1 (5,4,3 | 5,4,3,2,1), and a strictly climbing one where each number
is answered by the very next (2,4 | 1,2,3,4).
Re-traces as you type — nums1 (a subset), a pipe, then nums2 — e.g. "4,1,2 | 1,3,4,2"; nums2 holds 1–8 distinct integers and every nums1 value appears in it. Capped at 32 characters so the tiles stay readable.
Step 1 of 11: Every number is hunting the first bigger number to its right, so keep a stack of numbers still waiting — the moment a bigger one shows up it answers all of them at once, and a map caches each answer for the nums1 lookups. Variables: nums1 = [4, 1, 2], stack = ∅, map = {}.
Data
Code
1fun nextGreaterElement(nums1: IntArray, nums2: IntArray): IntArray {2 val nextGreater = HashMap<Int, Int>()3 val stack = ArrayDeque<Int>()4 for (num in nums2) {5 while (stack.isNotEmpty() && stack.last() < num) {6 nextGreater[stack.removeLast()] = num7 }8 stack.addLast(num)9 }10 return IntArray(nums1.size) { i -> nextGreater[nums1[i]] ?: -1 }11}
State
- nums1
- [4, 1, 2]
- stack
- ∅
- map
- {}
Why this step
Every number is hunting the first bigger number to its right, so keep a stack of numbers still waiting — the moment a bigger one shows up it answers all of them at once, and a map caches each answer for the nums1 lookups.
1 / 11
The same pattern also solves
Recognize the window, and these fall to the same skeleton.
- Next Greater Element II (LC 503)
The array is circular — run the same monotonic stack twice around so the tail can be answered by the head.
- Daily Temperatures (LC 739)
The same next-greater stack, but it records the distance to the warmer day instead of the value — no nums1 indirection.
- Online Stock Span (LC 901)
Flip the direction — a monotonic stack of previous-greater elements, answered as the prices stream in.
- Largest Rectangle in Histogram (LC 84)
The monotonic-stack boss — each bar pops the taller ones it ends, exactly this pop-when-smaller rule turned into areas.