LeetCode #739 Medium

Daily Temperatures

Daily Temperatures is LeetCode 739 (Medium). Given an array temperatures, return an array answer where answer[i] is the number of days after day i until a strictly warmer temperature. If no warmer day comes, answer[i] is 0.

  • Up to 10⁵ days, so scanning forward from every day (O(n²)) is too slow.
  • Temperatures are between 30 and 100.
Constraints
  • 1 <= temperatures.length <= 10⁵
  • 30 <= temperatures[i] <= 100
arraystackmonotonic-stack
Open on LeetCode ↗
02

Intuition

Think of the days that have not yet seen a warmer day as waiting. When a new day arrives, it settles every waiting day that is colder than it, starting with the most recent one. Most recent first is exactly what a stack gives.

The stack also has a useful shape: its temperatures never rise from bottom to top, because a warmer day would already have settled the colder ones below it.

How to spot this pattern

This problem asks "how many steps until the next larger value", which is the next greater element pattern: a monotonic stack of indices still waiting for an answer. The same stack solves Next Greater Element I and II, Online Stock Span (looking back instead of forward) and Largest Rectangle in Histogram.

03

Approach

Try it first

Before reading on: in [73, 74, 75, 71, 69, 72, 76, 73], day 6 (76) settles several earlier days at once. Which ones, and in what order? What do the days still waiting have in common just before it arrives?

1

Start with zeros and an empty stack

answer = [0] * n already holds the right value for every day that never sees a warmer one, so those days need no extra work. The stack will hold the indices of days still waiting.

2

Settle every colder day on top

For day i, while the stack is not empty and the day on top is colder than temperatures[i], pop it as prev and set answer[prev] = i - prev. Use while, not if: one warm day can end the wait of a whole run of colder days.

3

Push today's index

When the top is not colder, the loop stops: every day below it is at least as warm, so none can be settled. Push i. Store the index, not the temperature, because the answer is a distance between days and the temperature can be read back from the array.

4

Return the answer

Days left on the stack never met a warmer day and keep their 0. Each index is pushed once and popped at most once, so the whole scan is O(n) time even though it contains a nested loop.

04

Daily Temperatures solution in Python | C++ | Java

▶1class Solution:
▶2 def dailyTemperatures(self, temperatures: List[int]) -> List[int]:
▶3 answer = [0] * len(temperatures)
▶4 stack = []
▶5 for i, temp in enumerate(temperatures):
▶6 while stack and temperatures[stack[-1]] < temp:
▶7 prev = stack.pop()
▶8 answer[prev] = i - prev
▶9 stack.append(i)
▶10 return answer
tempsanswerstack73007410752071306940725076607370emptyevery day starts at 0, stack empty
answer[0, 0, 0, 0, 0, 0, 0, 0]0 = no warmer day yet
stackemptydays still waiting
Start. Every answer begins at 0, which is already right for any day that never sees a warmer one. The stack will hold the days whose answer is still open.
tempsanswerstack73007410752071306940725076607370730topstack empty → push day 0
today73day 0
stack[0]indices, temps falling
Nothing is waiting, so no comparison is needed. Day 0 now waits for its own warmer day. The stack stores the index, since the answer is a distance between days.
tempsanswerstack73017410752071306940725076607370empty74 > 73 → day 0 waits 1 − 0 = 1
today74day 1
popped73day 0
answer[0]1
stackempty
74 is warmer than 73. Day 0 is the most recent day still waiting, so day 1 is its first warmer day: pop it and write 1 − 0 = 1. The stack is now empty, so nothing else is waiting.
tempsanswerstack73017410752071306940725076607370741topstack empty → push day 1
today74day 1
stack[1]indices, temps falling
Nothing is waiting, so no comparison is needed. Day 1 now waits for its own warmer day. The stack stores the index, since the answer is a distance between days.
tempsanswerstack73017411752071306940725076607370empty75 > 74 → day 1 waits 2 − 1 = 1
today75day 2
popped74day 1
answer[1]1
stackempty
75 is warmer than 74. Day 1 is the most recent day still waiting, so day 2 is its first warmer day: pop it and write 2 − 1 = 1. The stack is now empty, so nothing else is waiting.
tempsanswerstack73017411752071306940725076607370752topstack empty → push day 2
today75day 2
stack[2]indices, temps falling
Nothing is waiting, so no comparison is needed. Day 2 now waits for its own warmer day. The stack stores the index, since the answer is a distance between days.
tempsanswerstack73017411752071306940725076607370752713top75 ≥ 71 → stop, push day 3
today71day 3
stack[2, 3]indices, temps falling
The top day has 75, which is not colder than 71, so the loop stops; every day below it is at least as warm, so none of them can be settled either. Day 3 now waits for its own warmer day. The stack stores the index, since the answer is a distance between days.
tempsanswerstack73017411752071306940725076607370752713694top71 ≥ 69 → stop, push day 4
today69day 4
stack[2, 3, 4]indices, temps falling
The top day has 71, which is not colder than 69, so the loop stops; every day below it is at least as warm, so none of them can be settled either. Day 4 now waits for its own warmer day. The stack stores the index, since the answer is a distance between days.
tempsanswerstack73017411752071306941725076607370752713top72 > 69 → day 4 waits 5 − 4 = 1
today72day 5
popped69day 4
answer[4]1
stack[2, 3]
72 is warmer than 69. Day 4 is the most recent day still waiting, so day 5 is its first warmer day: pop it and write 5 − 4 = 1. Then check the new top as well, since one warm day can settle several colder ones; that is why the code uses while, not if.
tempsanswerstack73017411752071326941725076607370752top72 > 71 → day 3 waits 5 − 3 = 2
today72day 5
popped71day 3
answer[3]2
stack[2]
72 is warmer than 71. Day 3 is the most recent day still waiting, so day 5 is its first warmer day: pop it and write 5 − 3 = 2. Then check the new top as well, since one warm day can settle several colder ones; that is why the code uses while, not if.
tempsanswerstack73017411752071326941725076607370752725top75 ≥ 72 → stop, push day 5
today72day 5
stack[2, 5]indices, temps falling
The top day has 75, which is not colder than 72, so the loop stops; every day below it is at least as warm, so none of them can be settled either. Day 5 now waits for its own warmer day. The stack stores the index, since the answer is a distance between days.
tempsanswerstack73017411752071326941725176607370752top76 > 72 → day 5 waits 6 − 5 = 1
today76day 6
popped72day 5
answer[5]1
stack[2]
76 is warmer than 72. Day 5 is the most recent day still waiting, so day 6 is its first warmer day: pop it and write 6 − 5 = 1. Then check the new top as well, since one warm day can settle several colder ones; that is why the code uses while, not if.
tempsanswerstack73017411752471326941725176607370empty76 > 75 → day 2 waits 6 − 2 = 4
today76day 6
popped75day 2
answer[2]4
stackempty
76 is warmer than 75. Day 2 is the most recent day still waiting, so day 6 is its first warmer day: pop it and write 6 − 2 = 4. The stack is now empty, so nothing else is waiting.
tempsanswerstack73017411752471326941725176607370766topstack empty → push day 6
today76day 6
stack[6]indices, temps falling
Nothing is waiting, so no comparison is needed. Day 6 now waits for its own warmer day. The stack stores the index, since the answer is a distance between days.
tempsanswerstack73017411752471326941725176607370766737top76 ≥ 73 → stop, push day 7
today73day 7
stack[6, 7]indices, temps falling
The top day has 76, which is not colder than 73, so the loop stops; every day below it is at least as warm, so none of them can be settled either. Day 7 now waits for its own warmer day. The stack stores the index, since the answer is a distance between days.
tempsanswerstack73017411752471326941725176607370766737top2 days never warmer → return answer
answer[1, 1, 4, 2, 1, 1, 0, 0]
left waiting6, 7keep 0
Answer = [1, 1, 4, 2, 1, 1, 0, 0]. The days still on the stack never met a warmer day, so their 0 stays. Each index was pushed once and popped at most once, so the nested loop does O(n) work in total.
05

Common pitfalls

Using if instead of while

✗ Wrong
if stack and temperatures[stack[-1]] < temp:
    prev = stack.pop()
    answer[prev] = i - prev
✓ Right
while stack and temperatures[stack[-1]] < temp:
    prev = stack.pop()
    answer[prev] = i - prev

Only the top day is settled. On [70, 60, 50, 80] day 3 settles day 2, but days 0 and 1 stay at 0 instead of 3 and 2.

Popping on equal temperatures

✗ Wrong
while stack and temperatures[stack[-1]] <= temp:
✓ Right
while stack and temperatures[stack[-1]] < temp:

An equal day is not warmer. On [70, 70, 80], <= settles day 0 with a wait of 1, but the right answer is 2.

Pushing temperatures instead of indices

✗ Wrong
stack.append(temp)
✓ Right
stack.append(i)

The answer is i - prev, a distance between days. A stack of temperatures has no way to tell where the waiting day was.

06

Complexity

Time
O(n)
Space
O(n)
Each index is pushed once and popped at most once. On falling temperatures nothing is popped and the stack holds all n days.
07

Daily Temperatures FAQ

Can it be solved without a stack?

Yes. Fill answer from right to left: for day i, start at j = i + 1 and, while temperatures[j] <= temperatures[i], jump ahead by answer[j] (stop if it is 0). The jumps skip days already known to be too cold. It is still O(n) and uses no stack, but it is harder to explain than the stack.

Should the stack go left to right or right to left?

Both work. Left to right (this page) settles a waiting day when its warmer day arrives. Right to left keeps a stack of candidate future days, pops the ones that are not warmer, and reads the answer from the top. The work and the stack size are the same.