Minimum Cost to Remove Stones
Reported by candidates from Airbnb's online assessment. Pattern, common pitfall, and the honest play if you blank under the timer.
A greedy that always removes the cheapest stone first looks right on both examples, then dies on the hidden tests. That's the trap in this Airbnb OA question, reported in April 2023. The row has n stones, and each removal costs 0, one-neighbor or two-neighbor depending on which adjacent stones are still standing. The endpoints and the single-stone case are where careless code breaks, because an end stone can never pay the two-neighbor price. Under the story it's a clean dynamic programming problem over adjacent pairs. If you blank on the reframe during the live assessment, StealthCoder runs invisibly on your desktop as a safety net and hands you the recurrence. Better to know it going in, though.
The problem
There are n stones in a row, indexed from 0 to n - 1. Stone i has two associated costs: oneNeighborCost[i] and twoNeighborCost[i]. Remove every stone in any order. At the moment stone i is removed, its cost is: twoNeighborCost[i] if both immediately adjacent stones i - 1 and i + 1 still exist. oneNeighborCost[i] if exactly one of those immediately adjacent stones still exists. 0 if neither immediately adjacent stone still exists. An index outside the row does not contain a stone. Return the minimum possible total cost of removing all stones. Function minimumRemovalCost(oneNeighborCost: int[], twoNeighborCost: int[]) → long Examples Example 1 oneNeighborCost = [3,4,5] twoNeighborCost = [10,1,10] return = 1 Remove stone 1 first for cost 1. Its removal leaves both end stones without an immediate neighbor, so both are then removed for free. Example 2 oneNeighborCost = [1,10,1] twoNeighborCost = [5,1,5] return = 1 Remove the middle stone first for cost 1. Both end stones are then isolated and can be removed for free. Constraints 1 <= n <= 5 * 10^4. oneNeighborCost.length == twoNeighborCost.length == n. 1 <= oneNeighborCost[i], twoNeighborCost[i] <= 1000.
Reported by candidates. Source: FastPrep
Pattern and pitfall
The trick: look at each adjacent pair (i, i+1). Whichever stone you remove first sees the other still standing, so that stone pays for that edge. Every edge gets assigned to exactly one endpoint, and a path has no cycles, so any assignment is achievable by some removal order. A stone holding 0 edges costs 0, holding 1 edge costs oneNeighborCost, and holding 2 edges costs twoNeighborCost. Ends only have one edge, so they can't hold two. Now it's a linear DP. State is whether the edge between i-1 and i was claimed by stone i. Transition on who claims the edge to i+1. That's O(n) with n up to 5*10^4. Pitfalls: using int instead of a long total, n equal to 1 returning 0, and charging an endpoint the two-neighbor cost. StealthCoder is your hedge if the edge-assignment idea doesn't come to you under the clock.
StealthCoder is the hedge for the one pattern you didn't drill. It runs invisibly during the screen share.
You can drill Minimum Cost to Remove Stones cold, or you can hedge it. StealthCoder runs invisibly during screen share and surfaces a working solution in under 2 seconds. The proctor sees the IDE. They don't see what's behind it. If you're reading this with an OA window open, you're who this was built for.
Get StealthCoderRelated leaked OAs
You've seen the question.
Make sure you actually pass Airbnb's OA.
Airbnb reuses patterns across OAs. If you're reading this with an OA window open, you're who this was built for. Works on HackerRank, CodeSignal, CoderPad, and Karat.
Minimum Cost to Remove Stones FAQ
What's the trick in the Minimum Cost to Remove Stones problem?+
Stop thinking about removal order. Think about each adjacent pair. The stone removed first in a pair pays for that neighbor. Assign every edge to one of its two endpoints, then each stone's cost depends only on how many edges it holds. Any assignment works because a row has no cycles.
Why does a greedy approach fail here?+
Removing the cheapest stone first ignores how it changes its neighbors' future costs. Removing a stone can make adjacent stones cheaper or free, or leave them paying more. Local choices don't capture that. The edge-assignment DP considers both owners of every pair, so it finds the true minimum.
What edge cases should I test for this Airbnb OA?+
Test n = 1, where the answer is 0 since no neighbors exist. Test n = 2, where one stone pays oneNeighborCost and the other is free. Check the end stones never use twoNeighborCost. Also use a long for the total, since n can reach 50,000 and costs reach 1000.
What's the time and space complexity?+
O(n) time with a rolling DP and O(1) extra space. You only need the best cost for the previous stone in two states: whether it claimed the shared edge or not. With n up to 5*10^4, even an O(n) array version is fine.
How do I prepare for this in 48 hours?+
Practice turning ordering problems into assignment problems on a path, then write a two-state linear DP. Run both provided examples by hand, since each answer is 1. Then write a brute-force permutation checker for tiny n and compare it against your DP on random small inputs.