Daily Temperatures
Given an array of integers temperatures represents the daily temperatures, return an array answer such that answer[i] is the number of days you have to wait after the ith day to get a warmer temperature. If there is no future day for which this is possible, keep answer[i] == 0.
- 1 <= temperatures.length <= 10⁵
- 30 <= temperatures[i] <= 100
temperatures = [73,74,75,71,69,72,76,73][1,1,4,2,1,1,0,0]temperatures = [30,40,50,60][1,1,1,0]Imagine you are tracking daily temperatures and want to know how many days you must wait for a warmer one. A naive approach would be to scan forward from every day until a higher temperature is found. This works, but in a long cooling trend (like a winter season), you will spend a massive amount of time re-scanning the same data, leading to O(N^2) complexity.
# Brute Force (O(N^2) Time, O(1) Space)
n = len(temperatures)
res = [0] * n
for i in range(n):
for j in range(i + 1, n):
if temperatures[j] > temperatures[i]:
res[i] = j - i
break
return resTo solve this in linear time, we use a Monotonic Stack. A key insight here is that we store indices (0, 1, 2...) rather than the temperatures themselves. Since the final answer requires the "distance" between days, storing indices allows us to calculate that distance instantly (current_index - waiting_index). The stack acts as a "Waiting Room" where days sit until a warmer challenger arrives to "rescue" them.
The strategy works as follows:
- Arrival: We scan through the temperatures day by day. Every day enters the Waiting Room by default.
- Rescue: When a new day arrives with a warmer temperature than the day at the top of the stack, that waiting day is "rescued." We calculate the wait time as current_index - waiting_index.
- Iterative Resolve: The new day continues to challenge everyone in the Waiting Room until it finds someone warmer than itself or the room is empty.
- Wait: Finally, the new day joins the stack to wait for its own future warmer day.
# Monotonic Stack (O(N) Time, O(N) Space)
n = len(temperatures)
res = [0] * n
stack = [] # Stores indices
for i in range(n):
# Current day challenges days in the waiting room
while stack and temperatures[i] > temperatures[stack[-1]]:
prev_index = stack.pop()
res[prev_index] = i - prev_index
# Current day starts its wait
stack.append(i)
return resBy only looking at each day twice—once when it enters the room and once when it is rescued—we achieve a perfect linear time. Any day left in the stack at the end simply never saw a warmer temperature, leaving its default wait time at 0.
Finding the Next Greater Element in Linear Time
How it Works
We use a stack to store indices of temperatures we haven't found a warmer day for yet.
When we see a temperature warmer than the stack top, we pop the index and calculate the difference.
The stack stays monotonic (always decreasing temperatures) because any higher value immediately clears out lower ones.
Complexity Insight
This runs in O(N) time because each temperature is pushed and popped exactly once. Using a stack converts a nested search into a single linear pass.