You are given k
bags. You are given a 0-indexed integer array weights
where weights[i]
is the weight of the i<sup>th</sup>
marble. You are also given the integer k
. Divide the marbles into the k
bags according to the following rules:
i<sup>th</sup>
marble and j<sup>th</sup>
marble are in a bag, then all marbles with an index between the i<sup>th</sup>
and j<sup>th</sup>
indices should also be in that same bag.i
to j
inclusively, then the cost of the bag is weights[i] + weights[j]
.The score after distributing the marbles is the sum of the costs of all the k
bags.
Return the difference between the maximum and minimum scores among marble distributions.
Example 1:
weights = [1,3,5,1], k = 2
Output: 4
Explanation:
The distribution [1],[3,5,1]
results in the minimal score of (1+1) + (3+1) = 6
.
The distribution [1,3],[5,1]
results in the maximal score of (1+3) + (5+1) = 10
.
Thus, we return their difference 10 - 6 = 4
.
Example 2:
weights = [1, 3], k = 2
Output: 0
Explanation: The only distribution possible is [1],[3]
. Since both the maximal and minimal score are the same, we return 0
.
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:
To solve this problem the hard way, we'll look at every single possible way to divide the marbles into bags. We will then figure out the cost for each of these divisions, and keep track of the best one we've seen so far.
Here's how the algorithm would work step-by-step:
def put_marbles_in_bags_brute_force(weights, num_bags):
number_of_marbles = len(weights)
# If we only have one bag, the cost is the first plus the last weight
if num_bags == 1:
return weights[0] + weights[number_of_marbles - 1]
min_cost = float('inf')
# Iterate through all possible divider placements
for i in range(1 << (number_of_marbles - 1)):
# Only consider combinations with the correct number of dividers
if bin(i).count('1') == num_bags - 1:
current_cost = 0
bag_start = 0
# Calculate cost based on current divider arrangement
for j in range(number_of_marbles - 1):
if (i >> j) & 1:
current_cost += weights[bag_start] + weights[j]
bag_start = j + 1
# Account for the last bag
current_cost += weights[bag_start] + weights[number_of_marbles - 1]
# Track minimum cost
min_cost = min(min_cost, current_cost)
return min_cost
The goal is to divide a row of marbles into a given number of bags such that the total score is maximized. The key insight is that only the weights of the marbles at the bag boundaries affect the score, so we focus on optimizing those selections.
Here's how the algorithm would work step-by-step:
def put_marbles_in_bags(weights, number_of_bags):
number_of_weights = len(weights)
if number_of_bags > number_of_weights:
return 0
# To maximize the score, calculate the boundary weights.
boundary_weights = []
for i in range(number_of_weights - 1):
boundary_weights.append(weights[i] + weights[i + 1])
# Need to sort to find the heaviest marbles at boundaries.
boundary_weights.sort(reverse=True)
total_score = 0
# We sum the largest 'number_of_bags - 1' boundary weights.
for i in range(number_of_bags - 1):
total_score += boundary_weights[i]
# Add the weights of the first and last marbles.
total_score += weights[0] + weights[-1]
return total_score
Case | How to Handle |
---|---|
weights is null or empty | Return 0 immediately as no marbles can be placed. |
k is less than or equal to 0 or greater than n (length of weights) | Return 0, indicating an invalid number of bags requested. |
weights contains only one element | Return 0, since at least two marbles are required to form a pair. |
Large input array size (near maximum allowed) | Ensure the chosen algorithm (e.g., sorting) scales efficiently (O(n log n) is preferred) to avoid exceeding time limits. |
Integer overflow when calculating the cost of a bag | Use long data type to store the cost of each bag to prevent potential integer overflow. |
All weights are the same value | The sorted sums will result in a predictable pattern, which the solution should handle correctly to find the minimum sum. |
k equals n (number of weights) | Return the sum of all adjacent pairs because each weight will be in its own bag. |
weights array contains negative values | The sorting operation will still work correctly, resulting in the minimum sum of k-1 largest values, even with negative values. |