Stacks & Queues
Loading
Loading
Stacks & Queues
Keep only the elements that can still matter, and popping becomes the answer.
By the end of this chapter
Push elements onto a stack, but before each push remove everything the newcomer makes irrelevant. What remains is sorted, and each removal tells you something.
def next_greater(nums): result = [-1] * len(nums) stack = [] # indices, values strictly decreasing for index, value in enumerate(nums): while stack and nums[stack[-1]] < value: result[stack.pop()] = value # THIS is the discovery stack.append(index) return resultConcept
It is tempting to read the while loop as tidying up before the push. It is not: the moment an element is popped, you have just learned its next greater element. Write the answer there.
Concept
Each index is pushed exactly once and popped at most once. The inner while loop can run many times in one iteration, but across the whole scan it cannot run more than n times in total. That is an amortised argument, and it is why O(n) is correct despite the nesting.
A sliding-window maximum needs the same idea plus expiry from the front, because an element can leave the window without ever being beaten. That makes it a deque rather than a stack.
rates = [1, 3, -1, -3, 5], k = 3deque [1]pushdeque [3]3 beats 1, so 1 can never matter againdeque [3, -1]-1 might matter once 3 expiresdeque [5]5 beats everything present[3, 3, 5]Can you recognise the pattern?
Each element needs to know about the nearest larger or smaller element in some direction.
Quick quiz
Sign in to keep a note here. It is free, and nobody else can see it.
Sign inWhat this chapter was for:
Before moving on: take the quiz above, and try 3 practice problems.