medium Minimum Number of Coins for Fruits
Problem Statement
You are given an array of integers prices where each element prices[i] represents the number of coins required to buy the ith fruit.
The fruit market has the following reward for each fruit:
- If you buy the ith fruit for
prices[i]coins, you can get the next(i + 1)fruits for free.
Note: Even if you have the option to take certain fruits for free, you can still choose to purchase them at their respective prices[j] to gain the reward for the next fruits.
Return the minimum number of coins needed to get all the fruits.
Examples
Example 1:
- Input: prices = [1, 6, 1, 2, 4]
- Expected Output: 2
- Explanation:
- Purchase the first fruit for 1 coin. Get next
i + 1 = 0 + 1 = 1fruit for free. - Get a second fruit for free.
- Purchase the third fruit for 1 coin, and get next
i + 1 = 2 + 1 = 3fruits for free. - Get fourth and fifth fruit for free.
- Total cost = 1 + 1 = 2.
- Purchase the first fruit for 1 coin. Get next
Example 2:
- Input: prices = [2, 3, 5, 1]
- Expected Output: 5
- Explanation:
- Purchase the first fruit for 2 coins. This allows you to take the second fruit for free.
- You get 2nd fruit for free, but still, purchase it with
3coins to get the third and fourth fruit for free. - So, total cost = 2 + 3 = 5.
Example 3:
- Input: prices = [3, 2, 1, 4]
- Expected Output: 4
- Explanation:
- Purchase the first fruit for 3 coins. Get next
i + 1 = 0 + 1 = 1fruit for free. - Get a second fruit for free.
- Purchase the third fruit for 1 coin, and get next
i + 1 = 2 + 1 = 3fruits for free. - Get fourth fruit for free.
- Total cost = 3 + 1 = 4.
- Purchase the first fruit for 3 coins. Get next
Constraints:
- 1 <= prices.length <= 1000
- 1 <= prices[i] <= 105
Try it yourself
Try solving this question here:
🎯 STRICT STANDOUT — Minimum Number of Coins for Fruits — problem
1. Why / judgment
Buying fruit i costs prices[i] and grants the next (i+1) fruits free (you may still buy inside the free range to extend coverage). Optimal substructure → DP: dp[i] = min cost to cover from i. Transition scans a range of previous buys — that range-min is monoqueue/deque optimizable. Judgment: not pure greedy on cheapest; free-span length depends on index.
2. Big-O derivation (K11)
n≤1000 naive DP O(n²) OK; n larger needs O(n) monoqueue on sliding min of dp.
dp[n]=0; for i=n-1..0 dp[i]=prices[i]+min(dp[j] for j in (i+1)..min(n, i+1+(i+1)+1? cover end)).
Worked [1,6,1,2,4] → 2.
3. Pattern + when-NOT (K12)
Name: DP + (OPTIONAL) MONOTONIC QUEUE RANGE-MIN
Recognition: rewards that unlock next segments; min cost cover all positions.
When-NOT: If free count fixed independent of i → simpler jump game / greedy. Unbounded classic coin change → different DP. Must buy all without free rules → just sum.
4. Edge hand-run (K13)
n=1 → prices[0].
prices increasing → often buy first + strategic later.
Never-buy-last-if-covered by earlier reward.
5. Interviewer follow-ups (model answers)
Q1. Why DP not greedy cheapest first?
A: Cheap late fruit may not cover early positions; coverage is directional forward from buy index.
Q2. Where monoqueue helps?
A: When transition is min over a contiguous sliding window of future dp states — deque keeps candidates increasing by dp value.
Q3. n=1000 enough for O(n²)?
A: Yes ~1e6 ops; still state definition clearly.
6. Short drills
Drill: [2,3,5,1] → 5.
Drill: write recurrence in words before code.
✅ Solution Minimum Number of Coins for Fruits
Problem Statement
You are given an array of integers prices where each element prices[i] represents the number of coins required to buy the ith fruit.
The fruit market has the following reward for each fruit:
- If you buy the ith fruit for
prices[i]coins, you can get the next(i + 1)fruits for free.
Note: Even if you have the option to take certain fruits for free, you can still choose to purchase them at their respective prices[j] to gain the reward for the next fruits.
Return the minimum number of coins needed to get all the fruits.
Examples
Example 1:
- Input: prices = [1, 6, 1, 2, 4]
- Expected Output: 2
- Explanation:
- Purchase the first fruit for 1 coin. Get next
i + 1 = 0 + 1 = 1fruit for free. - Get a second fruit for free.
- Purchase the third fruit for 1 coin, and get next
i + 1 = 2 + 1 = 3fruits for free. - Get fourth and fifth fruit for free.
- Total cost = 1 + 1 = 2.
- Purchase the first fruit for 1 coin. Get next
Example 2:
- Input: prices = [2, 3, 5, 1]
- Expected Output: 5
- Explanation:
- Purchase the first fruit for 2 coins. This allows you to take the second fruit for free.
- You get 2nd fruit for free, but still, purchase it with
3coins to get the third and fourth fruit for free. - So, total cost = 2 + 3 = 5.
Example 3:
- Input: prices = [3, 2, 1, 4]
- Expected Output: 4
- Explanation:
- Purchase the first fruit for 3 coins. Get next
i + 1 = 0 + 1 = 1fruit for free. - Get a second fruit for free.
- Purchase the third fruit for 1 coin, and get next
i + 1 = 2 + 1 = 3fruits for free. - Get fourth fruit for free.
- Total cost = 3 + 1 = 4.
- Purchase the first fruit for 3 coins. Get next
Constraints:
- 1 <= prices.length <= 1000
- 1 <= prices[i] <= 105
Solution
To solve the problem of finding the minimum number of coins needed to purchase all the fruits, we use a technique that involves iterating through the fruit prices from the last one to the first. By doing this, we can determine the most cost-effective way to buy each fruit and any subsequent fruits that might be available for free as a reward. We keep track of the best options using a deque (a double-ended queue) that helps us efficiently manage which fruits to consider for minimizing the total cost.
The deque is used to store the indices of the fruits in a way that allows us to quickly find the minimum cost for any given range of fruits. As we iterate through the prices, we update each fruit’s cost to include the cheapest possible way to get all the subsequent fruits. By the end of the loop, the total minimum cost to purchase all fruits is stored in the first element of the prices array, which is then returned as the result. This approach is both efficient and straightforward, ensuring we achieve the optimal solution.
Step-by-Step Algorithm
-
Initialize Variables:
- Determine the number of fruits, n, by finding the length of the prices array.
- Create a deque, deque, which will help in tracking the minimum prices efficiently as we move backward through the array.
-
Extend Prices Array:
- Extend the prices array by one element to avoid boundary issues when accessing future fruits.
- Set the last element, prices[n], to
0because no additional cost is required after the last fruit.
-
Start Iteration:
- Begin iterating through the prices array from the last fruit to the first. The loop runs from i = n - 1 to i = 0.
-
Calculate Maximum Covered Index:
- For each fruit i, calculate the maximum index that can be covered by buying this fruit. This is computed as maxCoveredIndex = min(n, 2 * i + 2), which ensures we don't go beyond the array bounds.
-
Manage the Deque:
- Remove Out of Range Elements: While the front of the deque contains indices greater than maxCoveredIndex, remove those elements. This ensures the deque only contains relevant indices that fall within the range of the current fruit's reward.
- Update Current Fruit Cost: Add the minimum cost of the next fruit in the deque to the current fruit's cost: prices[i] += prices[deque.peekFirst()]. This updates the price of the current fruit to include the best possible price for acquiring future fruits.
- Maintain Deque Order: While the deque is not empty and the cost of the current fruit is less than the cost of the fruit at the back of the deque, remove elements from the back of the deque. This ensures that the deque always remains sorted in increasing order of prices.
-
Add Current Fruit Index to Deque:
- Add the current index i to the deque using deque.addLast(i). This ensures that the deque will be considered for future fruits.
-
Return the Minimum Coins:
- After the loop ends, the minimum coins required to get all fruits starting from the first one is stored in prices[0]. Return this value.
Algorithm Walkthrough
Let's walk through the algorithm step by step with the input prices = [1, 6, 1, 2, 4].
-
Initial Setup:
- Start with
prices = [1, 6, 1, 2, 4]anddeque = []. - Append
0topricesto avoid boundary issues, soprices = [1, 6, 1, 2, 4, 0]. - Push
n = 5todeque, sodeque = [5].
- Start with
-
Iteration 1 (
i = 4):- Calculate
maxCoveredIndex = Math.min(5, 2 * 4 + 2) = 5. - No elements to remove from
dequesincedeque[0] = 5is within range. - Update
prices[4]:prices[4] = 4 + prices[5] = 4 + 0 = 4. - No elements to remove from the back of
dequesinceprices[i] < prices[deque[deque.length - 1]] (4 < 0)is not true. - Push
4todeque, sodeque = [5, 4].
- Calculate
-
Iteration 2 (
i = 3):- Calculate
maxCoveredIndex = Math.min(5, 2 * 3 + 2) = 5. - No elements to remove from
dequesincedeque[0] = 5is within range. - Update
prices[3]:prices[3] = 2 + prices[5] = 2 + 0 = 6. - Remove
4fromdequeasprices[3] < prices[4]. - Push
3todeque, sodeque = [5, 3].
- Calculate
-
Iteration 3 (
i = 2):- Calculate
maxCoveredIndex = Math.min(5, 2 * 2 + 2) = 5. - No elements to remove from
dequesincedeque[0] = 5is within range. - Update
prices[2]:prices[2] = 1 + prices[5] = 1 + 0 = 1. - Remove
3fromdequeasprices[2] < prices[3]. - Push
2todeque, sodeque = [5, 2].
- Calculate
-
Iteration 4 (
i = 1):- Calculate
maxCoveredIndex = Math.min(5, 2 * 1 + 2) = 4. - Remove
5fromdequesincedeque[0] = 5is out of range. Now, deque = [2] - Update
prices[1]:prices[1] = 6 + prices[2] = 6 + 1 = 7. - No elements are required to remove from the back.
- Push
1todeque, sodeque = [2, 1].
- Calculate
-
Iteration 5 (
i = 0):- Calculate
maxCoveredIndex = Math.min(5, 2 * 0 + 2) = 2. - No elements to remove from
dequesincedeque[0] = 2is within range. - Update
prices[0]:prices[0] = 1 + prices[2] = 1 + 1 = 2. - Push
0todeque, sodeque = [2, 0].
- Calculate
-
Final Output:
- After all iterations,
prices[0]is2, which is the minimum cost to buy all fruits.
- After all iterations,
Code
import java.util.*;
class Solution {
public int minimumCoins(int[] prices) {
int n = prices.length;
Deque<Integer> deque = new LinkedList<>();
deque.addLast(n);
prices = Arrays.copyOf(prices, n + 1);
prices[n] = 0; // Add a dummy fruit with 0 coins to avoid boundary issues.
// Iterate from the last fruit to the first
for (int i = n - 1; i >= 0; i--) {
// Calculate the maximum index that can be covered by the current fruit
int maxCoveredIndex = Math.min(n, 2 * i + 2);
// Remove all elements from the front that are outside the range of current fruit's reward
while (!deque.isEmpty() && deque.peekFirst() > maxCoveredIndex) {
deque.pollFirst();
}
// Update the cost of the current fruit by adding the minimum cost of reachable fruits
prices[i] += prices[deque.peekFirst()];
// Maintain the deque to keep it increasing
while (!deque.isEmpty() && prices[i] < prices[deque.peekLast()]) {
deque.pollLast();
}
// Add the current fruit index to the deque
deque.addLast(i);
}
// Return the minimum cost to get all fruits starting from the first one
return prices[0];
}
public static void main(String[] args) {
Solution solution = new Solution();
// Example 1
int[] prices1 = { 1, 6, 1, 2, 4 };
System.out.println("Example 1: " + solution.minimumCoins(prices1)); // Expected Output: 2
// Example 2
int[] prices2 = { 2, 3, 5, 1 };
System.out.println("Example 2: " + solution.minimumCoins(prices2)); // Expected Output: 5
// Example 3
int[] prices3 = { 3, 2, 1, 4 };
System.out.println("Example 3: " + solution.minimumCoins(prices3)); // Expected Output: 4
}
}
Complexity Analysis
Time Complexity
- Deque operations: Each index is pushed and popped from the deque at most once, making the time complexity for deque operations
. - Main Loop: The main loop iterates over each element of the
pricesarray exactly once, which is.
Overall, the time complexity of the algorithm is n is the number of elements in the prices array.
Space Complexity
- Deque: The space used by the deque is proportional to the number of elements it holds at any time, which is
in the worst case. - Auxiliary Space: An extra space is used to store the extended
pricesarray, but this is also.
Overall, the space complexity of the algorithm is
🎯 STRICT STANDOUT — Solution Minimum Number of Coins for Fruits
1. Why / judgment
Process right-to-left. Let dp[i] be min coins to obtain fruits i..n-1. Buying at i covers up through index i+(i+1) (= 2i+1) free after i, so you need min dp among positions you might still need to pay beyond that cover, carefully — follow the page’s transition; verify on samples. Core: local choice + optimal tail.
2. Big-O derivation (K11)
[1,6,1,2,4]:
Optimal: buy idx0 (cost1) free idx1; buy idx2 (cost1) free idx3,4 → total 2 ✓
[2,3,5,1] → 5 ✓
[3,2,1,4] → 4 ✓
Naive transitions O(n) each → O(n²) ≤ 1e6.
Monoqueue can maintain sliding mins if rewritten as window minima.
3. Pattern + when-NOT (K12)
Name: RIGHT-TO-LEFT DP (RANGE MIN OPTIONAL)
Recognition: index-dependent free span after purchase.
When-NOT: Greedy take all min prices without coverage logic → wrong.
4. Edge hand-run (K13)
n=1 [9] → 9.
All free from first buy when n small relative to reward — verify cover reaches n-1.
5. Interviewer follow-ups (model answers)
Q1. Why start from the end?
A: Tail costs are independent of how you reached them; natural base dp[n]=0.
Q2. Is this monoqueue pattern primarily?
A: Underlying is DP; monoqueue is an optimization of the min-range transition — pattern transfer: recognize range-min in DP ⇒ deque.
Q3. Interview follow-up n=1e5?
A: Must get O(n) or O(n log n): monoqueue / sparse table on dp.
6. Short drills
Drill: recompute sample 3 → 4.
Drill: list which indices paid in sample 1.
Recognize it: Matching / nesting, or “next greater / smaller” → LIFO, or a monotonic stack.
▶ Visualize this problem (step it, predict each fork)
🤖 Don't fully get this? Learn it with Claude
Stuck on Minimum Number of Coins for Fruits? Open Claude, copy a block below, and it'll teach you this exact concept — visually and interactively.
Progressively stronger hints — you still solve it.
I'm working on the problem **Minimum Number of Coins for Fruits** (DSA). Give me a HINT LADDER: start with the tiniest nudge, then wait. Only reveal the next, stronger hint when I ask. Do NOT show the full solution unless I type 'show solution'. Keep me doing the thinking. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
See the technique, not just code.
Explain the optimal approach to **Minimum Number of Coins for Fruits** with a VISUAL walkthrough: trace it on a small concrete example using ASCII art / a step-by-step diagram, narrate what changes each step, then give time & space complexity with a one-line derivation. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
Catch bugs, edge cases, sub-optimality.
I'll paste my solution to **Minimum Number of Coins for Fruits**. Review it for correctness, missed edge cases, and time/space complexity, then coach me toward the optimal — don't just rewrite it. Ask me to paste my code now. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
Lock in recognition with look-alikes.
Give me 2 problems that use the SAME underlying pattern as **Minimum Number of Coins for Fruits**. For each, let me attempt first, then review my answer and name the trigger signal that reveals the pattern. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.