2706. Buy Two Chocolates - Explanation
Description
You are given an integer array prices representing the prices of various chocolates in a store. You are also given a single integer money, which represents your initial amount of money.
You must buy exactly two chocolates in such a way that you still have some non-negative leftover money. You would like to minimize the sum of the prices of the two chocolates you buy.
Return the amount of money you will have leftover after buying the two chocolates. If there is no way for you to buy two chocolates without ending up in debt, return money. Note that the leftover must be non-negative.
Example 1:
Input: prices = [1,3,2], money = 5
Output: 2Explanation: Buy the two chocolates with prices 1 + 2. The leftover money is 5 - 3 = 2.
Example 2:
Input: prices = [2,5,1,2], money = 3
Output: 0Explanation: Buy the two chocolates with prices 1 + 2. The leftover money is 3 - 3 = 0.
Example 3:
Input: prices = [2,2,4,3], money = 2
Output: 2Explanation: There is no way to buy two chocolates. So, we return the given money 2.
Constraints:
2 <= prices.length <= 501 <= prices[i], money <= 100
Topics
Prerequisites
Before attempting this problem, you should be comfortable with:
- Arrays - Basic array traversal and accessing elements by index
- Sorting - Understanding how sorting works and its time complexity
- Greedy Algorithms - Making locally optimal choices to find a global optimum
1. Brute Force
Intuition
We want to buy two chocolates and maximize the leftover money, which means we should minimize the total cost of the two chocolates. The brute force approach tries every possible pair of chocolates and keeps track of the maximum leftover (or equivalently, the pair with minimum total cost that we can afford).
Algorithm
- Initialize result to
-1(indicating no valid purchase found yet). - For each pair of chocolates
(i, j)wherei < j:- If the sum of their prices is within our budget, calculate the leftover money.
- Update result with the maximum leftover found.
- If no valid pair was found (result is
-1), return the original money (we buy nothing). - Otherwise, return the maximum leftover amount.
class Solution:
def buyChoco(self, prices: List[int], money: int) -> int:
res = -1
for i in range(len(prices)):
for j in range(i + 1, len(prices)):
if prices[i] + prices[j] <= money:
res = max(res, money - prices[i] - prices[j])
return res if res != -1 else moneyTime & Space Complexity
- Time complexity:
- Space complexity: extra space.
2. Sorting
Intuition
To maximize leftover money, we need to buy the two cheapest chocolates. After sorting the prices, the two cheapest chocolates will be at the beginning of the array. We just need to check if we can afford them.
Algorithm
- Sort the prices array in ascending order.
- Calculate the cost of buying the two cheapest chocolates (first two elements).
- If this cost exceeds our money, return the original money (we buy nothing).
- Otherwise, return money minus the cost of the two chocolates.
Time & Space Complexity
- Time complexity:
- Space complexity: or depending on the sorting algorithm.
3. Greedy
Intuition
We can find the two cheapest chocolates in a single pass without sorting. As we iterate through the prices, we maintain the two smallest values seen so far. This gives us the optimal pair to buy.
Algorithm
- Initialize two variables to track the smallest (
min1) and second smallest (min2) prices, both set to infinity. - Iterate through each price:
- If the current price is less than
min1, updatemin2to be the oldmin1, andmin1to be the current price. - Otherwise, if the current price is less than
min2, updatemin2to be the current price.
- If the current price is less than
- Calculate the leftover money after buying chocolates at
min1andmin2prices. - If leftover is non-negative, return it; otherwise, return the original money.
Time & Space Complexity
- Time complexity:
- Space complexity: extra space.
Common Pitfalls
Returning Leftover When You Cannot Afford Both Chocolates
If the sum of the two cheapest chocolates exceeds your money, you should return the original money (buy nothing), not a negative leftover or zero.
# Wrong: returning negative leftover
return money - min1 - min2 # Could be negative
# Correct: check if affordable firstNot Updating Both Minimums Correctly
When finding a new smallest price, forgetting to shift the old minimum to become the second minimum loses track of valid candidates.
# Wrong: losing second minimum
if p < min1:
min1 = p # min2 is never updated with old min1
Sign in to join the discussion