Final Prices With a Special Discount in a Shop
Read the prices left to right. Keep a stack of indices whose discount has not been found yet. When price prices[i] arrives, every waiting item on top with a price >= prices[i] has just found its first cheaper-or-equal item: subtract prices[i] from it and pop it. Then push i, because it now waits for its own discount.
Prices on the stack strictly increase from bottom to top. Anything ≤ a waiting item below it would already have paid that item off and popped it.
Problem
A shop sells items in a row. prices[i] is the price of item i.
The shop has a special deal: when you buy item i, you get a discount equal to prices[j], where j is the first index after i with prices[j] <= prices[i]. If there is no such item, you get no discount.
Return an array where entry i is the price you actually pay for item i.
An integer array prices.
An array answer of the same length, where answer[i] is prices[i] minus its discount.
8 gets 4 off (4 is the first price ≤ 8 to its right). 4 gets 2 off. 6 gets 2 off. 2 gets nothing (no price ≤ 2 after it). 3 is last, so no discount.
Prices only go up, so no item ever finds a cheaper-or-equal one after it.
10 gets 1 off. The first 1 gets 1 off from the second 1, because equal counts. The second 1 and 6 get nothing.
- • 1 ≤ prices.length ≤ 500
- • 1 ≤ prices[i] ≤ 1000
First, think yourself
Before opening any solution, try to answer these on paper. Use hints only when stuck — each hint is counted.
- 1.
For one item, which item to its right gives the discount? The cheapest one, or the first good one?
- 2.
Does a price that is exactly equal count?
- 3.
If item 5 is waiting for a discount and item 7 comes along that is ≤ it, does item 5 still need to look further?
- 4.
While you read left to right, which items are still "waiting" for their discount?
- 5.
If a new price is small enough to pay off one waiting item, which waiting items does it pay off first?
Brute force approach
Optimized approach
Why does this algorithm work?
Dry run
All approaches compared
| Approach | Idea | Time | Space |
|---|---|---|---|
| Brute Force | For each item, walk right until the first price ≤ it | O(N²) | O(1) |
| Optimal | Keep unpaid items on a stack; a new price ≤ top pays off and pops them | O(N) | O(N) |
Why does this belong to this pattern?
- “the first index j after i”"First to the right" → a next-element question, not min/max of a range.
- “prices[j] <= prices[i]”We want something smaller (or equal) → the stack keeps the bigger ones waiting, so it is increasing.
- “otherwise no discount”Items left on the stack at the end get a default (here: full price).
This is the anchor for next smaller. It is the mirror of next greater: there the stack is decreasing and a bigger arrival pops; here the stack is increasing and a smaller-or-equal arrival pops. The only twist in this problem is the =: an equal price counts, so we pop on >=, not >. The next question (GFG Next Smaller Element) uses strictly smaller and shows the right-to-left way of building the same answer.
Don't make this mistake
The problem says "less than or equal". With >, [10, 1, 1, 6] gives the first 1 no discount and returns [9, 1, 1, 6] instead of [9, 0, 1, 6].
Pattern-confusion trap: the next-greater template pops when a bigger value arrives, so the stack decreases. Copying it here gives each item the first more expensive item, which is the wrong discount. Ask: "what kind of arrival settles a waiting item?" Here it is a cheaper one, so the stack must increase.
The discount is the first price ≤ mine, not the smallest. In [8, 4, 6, 2, 3], item 8 gets 4 off, not 2.
When we pop, we must write into that item's slot in ans. With only the price on the stack you do not know where it came from (and prices can repeat).
Want to implement this?
Write it yourself on LeetCode, then come back and compare your code with the solutions above.
Open coding workspaceHow this concept connects to System Design & C++ Systems
Top engineering interviews test whether you understand how algorithms like Monotonic Stack translate into production architectures and low-level memory mechanics.