You are given an array of positive integers beans
, where each integer represents the number of magic beans found in a particular magic bag.
Remove any number of beans (possibly none) from each bag such that the number of beans in each remaining non-empty bag (still containing at least one bean) is equal. Once a bean has been removed from a bag, you are not allowed to return it to any of the bags.
Return the minimum number of magic beans that you have to remove.
Example 1:
Input: beans = [4,1,6,5] Output: 4 Explanation: - We remove 1 bean from the bag with only 1 bean. This results in the remaining bags: [4,0,6,5] - Then we remove 2 beans from the bag with 6 beans. This results in the remaining bags: [4,0,4,5] - Then we remove 1 bean from the bag with 5 beans. This results in the remaining bags: [4,0,4,4] We removed a total of 1 + 2 + 1 = 4 beans to make the remaining non-empty bags have an equal number of beans. There are no other solutions that remove 4 beans or fewer.
Example 2:
Input: beans = [2,10,3,2] Output: 7 Explanation: - We remove 2 beans from one of the bags with 2 beans. This results in the remaining bags: [0,10,3,2] - Then we remove 2 beans from the other bag with 2 beans. This results in the remaining bags: [0,10,3,0] - Then we remove 3 beans from the bag with 3 beans. This results in the remaining bags: [0,10,0,0] We removed a total of 2 + 2 + 3 = 7 beans to make the remaining non-empty bags have an equal number of beans. There are no other solutions that removes 7 beans or fewer.
Constraints:
1 <= beans.length <= 105
1 <= beans[i] <= 105
When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
The brute force approach involves trying out every single possibility of how many beans to remove. It's like we're testing out all scenarios until we find the one that requires removing the fewest beans. We do this by checking each possible target value that all the bean piles can be reduced to.
Here's how the algorithm would work step-by-step:
def remove_minimum_magic_beans_brute_force(magic_beans):
minimum_removed_beans = float('inf')
# Consider each number of beans as a potential target
for potential_target in magic_beans:
total_removed_beans = 0
# Calculate the number of beans to remove for current target
for bean_count in magic_beans:
beans_to_remove = bean_count - potential_target
# Only count removals if the target is less than the current pile
if beans_to_remove > 0:
total_removed_beans += beans_to_remove
# Update min if current target requires fewer removals
minimum_removed_beans = min(minimum_removed_beans, total_removed_beans)
# The target of zero must be considered
total_removed_beans_zero = sum(magic_beans)
minimum_removed_beans = min(minimum_removed_beans, total_removed_beans_zero)
return minimum_removed_beans
To minimize the magic beans removed, we want to keep as many beans as possible on the same level. The key idea is to find the most frequent level and then remove beans from all the other bags to match that level.
Here's how the algorithm would work step-by-step:
def removing_minimum_number_of_magic_beans(
magic_beans: list[int],
) -> int:
total_beans = sum(magic_beans)
magic_beans.sort()
minimum_removed = float('inf')
# Iterate through each bag to find the optimal height
for i, current_bean_count in enumerate(magic_beans):
# Calculate beans removed if all bags matched current height
removed_beans_count = total_beans - (
len(magic_beans) - i
) * current_bean_count
# Update minimum if current removal is less
minimum_removed = min(minimum_removed, removed_beans_count)
return minimum_removed
Case | How to Handle |
---|---|
Null or empty input array | Return 0 immediately since there are no beans to remove. |
Input array with only one element | Return 0 because all bags already have the same number of beans. |
Input array with all elements having the same value | Return 0 because no beans need to be removed. |
Large input array (performance consideration) | Sort the array to efficiently determine the optimal target value; time complexity is O(n log n). |
Integer overflow when calculating the total number of beans for removal | Use a 64-bit integer type (long in Java/C++) to store the sum to prevent potential overflow. |
Input array containing large integer values that could lead to overflow when summing | Use long data type to prevent overflow when calculating the total sum and bean removals. |
Array with very skewed distribution (one very large value compared to others) | The sorting and iterative calculation will still correctly identify the optimal target value. |
Array contains zeros | The algorithm functions correctly with zeros, treating them as a valid number of beans in a bag; if zero is the target value all other beans will be removed. |