You have an inventory
of different colored balls, and there is a customer that wants orders
balls of any color.
The customer weirdly values the colored balls. Each colored ball's value is the number of balls of that color you currently have in your inventory
. For example, if you own 6
yellow balls, the customer would pay 6
for the first yellow ball. After the transaction, there are only 5
yellow balls left, so the next yellow ball is then valued at 5
(i.e., the value of the balls decreases as you sell more to the customer).
You are given an integer array, inventory
, where inventory[i]
represents the number of balls of the ith
color that you initially own. You are also given an integer orders
, which represents the total number of balls that the customer wants. You can sell the balls in any order.
Return the maximum total value that you can attain after selling orders
colored balls. As the answer may be too large, return it modulo 109 + 7
.
Example 1:
Input: inventory = [2,5], orders = 4 Output: 14 Explanation: Sell the 1st color 1 time (2) and the 2nd color 3 times (5 + 4 + 3). The maximum total value is 2 + 5 + 4 + 3 = 14.
Example 2:
Input: inventory = [3,5], orders = 6 Output: 19 Explanation: Sell the 1st color 2 times (3 + 2) and the 2nd color 4 times (5 + 4 + 3 + 2). The maximum total value is 3 + 2 + 5 + 4 + 3 + 2 = 19.
Constraints:
1 <= inventory.length <= 105
1 <= inventory[i] <= 109
1 <= orders <= min(sum(inventory[i]), 109)
This problem involves maximizing the profit from selling colored balls with diminishing values. The key insight is to sell the most expensive balls first. We can achieve this using a greedy approach combined with efficient calculations.
Approach:
Sort: Sort the inventory
array in descending order. This ensures that we always consider the most valuable balls first.
Iterative Selling: Iterate through the sorted inventory
. For each distinct value (or batch of balls with the same value), we calculate the profit from selling as many balls as possible at that value. We need to handle two cases:
Case 1: Enough balls of the current value to satisfy all remaining orders: We can sell all the balls with the current value. The total profit is calculated as the sum of an arithmetic series.
Case 2: Not enough balls of the current value: We sell as many balls as we can from the current value. Then, we move to the next lower value.
Modulo Operation: Since the answer can be very large, we use the modulo operator (%
) with 10^9 + 7
to prevent integer overflow.
Time Complexity Analysis:
O(n log n)
, where n
is the length of the inventory
array.O(n)
. In the worst case, we iterate through the entire sorted array. The arithmetic series summation is O(1).Therefore, the overall time complexity is O(n log n), dominated by the sorting step.
Space Complexity Analysis:
The space complexity is O(1) (or O(log n) if the sorting algorithm uses extra space) because we are modifying the input array in-place, and we don't use any auxiliary data structures whose size scales with the input.
Code Implementation (Python):
class Solution:
def maxProfit(self, inventory: List[int], orders: int) -> int:
inventory.sort(reverse=True) # Sort in descending order
mod = 10**9 + 7
ans = 0
i = 0
n = len(inventory)
while orders > 0:
while i < n and inventory[i] == inventory[0]:
i += 1
next_val = 0 if i == n else inventory[i]
count = i
diff = inventory[0] - next_val
total_at_current_price = count * diff
if total_at_current_price >= orders:
# Case 2: Not enough balls of the current value
decrement = orders // count
a1, an = inventory[0] - decrement + 1, inventory[0]
ans += (a1 + an) * decrement // 2 * count
ans += (inventory[0] - decrement) * (orders % count)
else:
# Case 1: Enough balls to satisfy orders
a1, an = next_val + 1, inventory[0]
ans += (a1 + an) * diff // 2 * count
inventory[0] = next_val
orders -= total_at_current_price
ans %= mod
return ans
This Python code implements the approach efficiently. The other languages (Java, C++, Go) would follow a very similar structure, differing only in syntax and specifics of array handling and sorting. The core logic remains the same: sorting, iterative selling with efficient arithmetic series summation, and modulo operation for preventing overflow.