Understand
30-second explanation
Build the interview-ready mental model before comparing implementations.
Keep a stack of *indices* whose warmer day hasn't been found yet, with their temperatures in decreasing order. For each new day, while it's warmer than the temperature at the index on top of the stack, pop that index and record the gap (currentIndex − poppedIndex) as its answer. Push the current index. Each index is pushed and popped once → O(n) time, O(n) space. The monotonic stack avoids re-scanning future days.
Interview contextWhat is testedWhere candidates slipHow to stand outExplore interview contextHide interview context
What's being tested
Whether you recognise a 'next greater element' problem and deploy a monotonic stack of indices for O(n), instead of the obvious O(n²) double loop.
Where candidates slip
Storing temperatures instead of indices (losing the distance), using the wrong monotonic direction, or recomputing answers with a nested scan.
How to stand out
Name the monotonic-stack pattern, explain the amortized O(n) argument (each index pushed/popped once), and note that leftover stack entries correctly default to 0.
Choose
Compare the available approaches
Use constraints and trade-offs to select the route you can defend in an interview.
Interactive decision treeInteractiveChoose the right approachFirst decision previewday i, temp tstack non-empty AND temps[top] < t?YesNoExplore the full treeCollapse the tree
Learn & trace
Build each solution step by step
Move from the core idea to a visual trace, implementation, proof, and edge cases.
Approach 1 of 2
Brute Force — Scan Forward (Baseline)
1Hint 1Explore hintHide hint
For a single day, how would you find its next warmer day with no extra structures?
2Hint 2Explore hintHide hint
For each i, scan j = i+1, i+2, ... until temps[j] > temps[i]; record j - i (or 0 if none).
3Hint 3Explore hintHide hint
Correct but O(n²) — a descending run like [100, 99, ..., 30] makes every inner scan long. That repetition is the cue for a stack.
A · Core idea
For every day i, walk forward until a strictly warmer day j is found and store j − i; if none, leave 0.
Why mention it. It directly encodes the definition and confirms the answer format. Why it's too slow. With n up to 10⁵, the nested forward scan is O(n²) ≈ 10¹⁰. The wasted work is re-scanning the same future days for many starting points — exactly what a stack of pending days eliminates.
B · Visual dry run
Interactive dry run
Select a frame to connect the decision with its visual state.
temperatures = [73, 74, 75]i=0 (73)
j=1 → 74 > 73 → ans=1
ans[0]=1[1, 1, 0]C · Code with teaching comments
Reference implementation previewpublic int[] dailyTemperatures(int[] temperatures) { int n = temperatures.length; int[] answer = new int[n]; for (int i = 0; i < n; i++) { for (int j = i + 1; j < n; j++) {Explore the full codeHide the full code
D · Why it works and complexityO(n²) timeO(1) spaceOpen the invariant and proofExplore the proofHide the proof
The brute force repeatedly re-examines the same cold stretch. If we instead remember the days still waiting for a warmer day, one warm day can resolve many of them at once — turning repeated forward scans into single pops.
ComplexityO(n²) time, O(1) space — For each of n days we may scan up to n later days → O(n²) worst case (e.g. a long descending sequence), constant extra space.
E · Edge cases and pitfalls2O(n²) — times out at n = 10⁵.Explore edge casesHide edge cases
Pitfalls
- O(n²) — times out at n = 10⁵.
- Forgetting break, which would record the farthest rather than nearest warmer day.
Approach 2 of 2 · Optimal
Monotonic Decreasing Stack (Optimal)
1Hint 1Explore hintHide hint
Many days might be 'waiting' for a warmer day at once. If you keep those waiting days somewhere, what happens when a warm day finally arrives?
2Hint 2Explore hintHide hint
Keep a stack of indices whose answer isn't known yet, kept so their temperatures are decreasing. A new warmer day resolves everything colder on top.
3Hint 3Explore hintHide hint
While temps[stack.top] < today, pop and set answer[popped] = today - popped. Then push today. Each index is pushed and popped once → O(n).
A · Core idea
Sweep left to right maintaining a stack of indices of days still awaiting a warmer day, kept in decreasing temperature order from bottom to top.
The invariant. Every index on the stack is a day whose next-warmer-day hasn't been found yet, and their temperatures strictly decrease as you go up the stack. So the top is always the coldest unresolved day so far — and the first one a new warm day can settle.
Processing day `i`. Compare temperatures[i] to the temperature at the index on top. While the top day is colder (temps[top] < temps[i]), day i is its answer: pop the index j and set answer[j] = i − j (the number of days it waited). Repeat — one warm day can resolve a whole descending run of colder days. When the top is not colder (or the stack is empty), push i; it now waits for its own warmer day. The decreasing order is preserved because we only push after popping everything smaller.
Why store indices, not temperatures. The answer is a distance in days, so we need the position to compute i − j. Temperatures alone can't recover that. (The bounded value range also makes indices natural here.)
Unresolved days default to 0. Any index still on the stack after the sweep had no warmer day ahead. Because we initialise answer to all zeros, those positions are already correct — no cleanup needed.
Why it's O(n), not O(n²). It looks like a nested loop, but the inner while only pops indices, and each index can be popped at most once over the entire run (after which it's gone). The total pops plus pushes is bounded by 2n, so the amortized cost per day is constant. This is the hallmark of the monotonic-stack technique: it pays for the inner loop with a global push/pop budget.
Why 'decreasing'. We want the next greater element, so we keep candidates that are still 'looking up' for something bigger — a decreasing stack. (For a next-smaller problem you'd keep an increasing stack and flip the comparison.)
B · Visual dry run
Interactive dry run
Select a frame to connect the decision with its visual state.
temperatures = [73, 74, 75, 71, 69, 72, 76, 73]Array state
i=2 (75)
after pushes/pops, only index 2 waiting
[1, 1, 4, 2, 1, 1, 0, 0]C · Code with teaching comments
D · Why it works and complexityO(n) timeO(n) spaceOpen the invariant and proofExplore the proofHide the proof
A monotonic stack stores only the elements whose answer is still pending, in the order a future element would resolve them. That converts 'for each element, look ahead' from quadratic to linear. The same machine — sometimes increasing, sometimes decreasing, sometimes storing indices for spans — solves Next Greater Element, Online Stock Span, Largest Rectangle in Histogram, and Trapping Rain Water.
ComplexityO(n) time, O(n) space — Each index is pushed exactly once and popped at most once, so the total number of stack operations across the whole run is ≤ 2n. The inner while loop is therefore amortized O(1) per day → O(n) time. The stack can hold up to n indices → O(n) space.
E · Edge cases and pitfalls8temperatures = [30] — Single day, no warmer future → answer [0]; index 0 stays on the stack.Explore edge casesHide edge cases
Edge cases handled
temperatures = [30]Single day, no warmer future → answer [0]; index 0 stays on the stack.temperatures = [30, 40, 50, 60]Strictly increasing → each day pops the previous immediately → [1,1,1,0].temperatures = [100, 90, 80]Strictly decreasing → nothing ever pops; all answers stay 0 → [0,0,0].ties, e.g. [70, 70, 75]Equal temps don't resolve (strict <), so day 0 and day 1 both wait for 75 → [2,1,0].
Pitfalls
- Storing temperatures instead of indices — can't compute the day distance.
- Using <= instead of < — wrongly resolves equal-temperature days.
- Wrong monotonic direction (increasing) — solves next-smaller, not next-greater.
- Re-scanning to fill answers instead of trusting the default 0 for leftover indices.
Practice
Try the solution yourself
Edit the optimal implementation, test another input, and observe the result.
Editable code previewpublic int[] dailyTemperatures(int[] temperatures) { int n = temperatures.length; int[] answer = new int[n]; // defaults to 0 Deque<Integer> stack = new ArrayDeque<>(); // indices, temps decreasing for (int i = 0; i < n; i++) {Explore the playgroundClose the playground
Avoid mistakes
Recognize the interview traps
Understand why common attempts fail before reviewing the corrected implementation.
1Storing temperatures instead of indices
The answer is the distance in days, which requires positions. A stack of temperatures can't recover how far apart the days are.
Explore the code comparisonHide the code comparison
Storing temperatures instead of indices
The answer is the distance in days, which requires positions. A stack of temperatures can't recover how far apart the days are.
Don't write this
stack = []
for i, t in enumerate(temperatures):
while stack and stack[-1] < t: # storing temps
stack.pop()
# no way to compute i - j here
stack.append(t)Write this instead
stack = [] # store indices
for i, t in enumerate(temperatures):
while stack and temperatures[stack[-1]] < t:
j = stack.pop()
answer[j] = i - j
stack.append(i)2Non-strict comparison on ties
The problem asks for a strictly warmer day. Using <= pops days with the SAME temperature, recording a warmer-day distance that isn't actually warmer.
Explore the code comparisonHide the code comparison
Non-strict comparison on ties
The problem asks for a strictly warmer day. Using <= pops days with the SAME temperature, recording a warmer-day distance that isn't actually warmer.
Don't write this
while (!stack.isEmpty() && temperatures[stack.peek()] <= temperatures[i]) {
int j = stack.pop();
answer[j] = i - j;
}Write this instead
while (!stack.isEmpty() && temperatures[stack.peek()] < temperatures[i]) {
int j = stack.pop();
answer[j] = i - j;
}Revise
Carry the pattern into the interview
Pattern to remember
Monotonic decreasing stack of indices (next greater element)
Code pattern to memorize
stack = [] # indices, temps decreasing
for i, t in enumerate(temps):
while stack and temps[stack[-1]] < t:
j = stack.pop()
ans[j] = i - j
stack.append(i)
return ans # unresolved indices keep 0Rules to remember
- 1Store indices, not temperatures — you need the index distance for the answer.
- 2Maintain a decreasing stack: pop while
temps[top] < current, because the current day is the answer for every colder day still waiting. - 3The answer for a popped index
jisi − j(days waited), not the temperature. - 4Indices never resolved (no warmer day ahead) stay at the default 0 — pre-fill the result with zeros.
- 5Each index is pushed once and popped at most once → the inner while loop is amortized O(1), giving overall O(n).
Use this pattern when
- Next greater / next smaller element, or 'how far until a bigger value'
- Span problems: stock span, largest rectangle in histogram, trapping rain water
- Any 'for each element, find the nearest later element satisfying a comparison' in O(n)
Choose another pattern when
- You need the next greater in *circular* order → still a monotonic stack, but iterate 2n with modulo
- Comparison isn't a simple monotone relation → a stack invariant may not hold
- You only need one query, not per-element answers → a single scan may suffice
Interview takeaway
A monotonic stack converts an O(n²) 'look ahead for the next bigger value' into O(n) by holding only the *unresolved* candidates in sorted order. Recognising 'next greater element' framing — and storing indices so you can measure distance — is the reusable trick across span and histogram problems.
Continue
Transfer the pattern to another problem
Use a direct variation or pattern sibling to prove the idea is reusable.
Transferable patternMonotonic stack for next-greater-element / span problems. Recognise it when each element needs the nearest later element satisfying a comparison: keep only unresolved candidates in monotone order and store indices for distances. Same machine as Next Greater Element, Stock Span, and Largest Rectangle in Histogram.
Practice queueDirect variations and pattern siblings
Direct follow-ups
- Next Greater Element IComing soonMonotonic stack to precompute next-greater, then map via a hash table.
- Next Greater Element IIComing soonCircular array — iterate 2n with index % n, same decreasing stack.
- Online Stock SpanComing soonMonotonic stack storing (price, span) to answer streaming spans in amortized O(1).
- Largest Rectangle in HistogramComing soonMonotonic increasing stack of indices to find left/right smaller boundaries.