Alice is a caretaker of n
gardens and she wants to plant flowers to maximize the total beauty of all her gardens.
You are given a 0-indexed integer array flowers
of size n
, where flowers[i]
is the number of flowers already planted in the ith
garden. Flowers that are already planted cannot be removed. You are then given another integer newFlowers
, which is the maximum number of flowers that Alice can additionally plant. You are also given the integers target
, full
, and partial
.
A garden is considered complete if it has at least target
flowers. The total beauty of the gardens is then determined as the sum of the following:
full
.partial
. If there are no incomplete gardens, then this value will be 0
.Return the maximum total beauty that Alice can obtain after planting at most newFlowers
flowers.
Example 1:
Input: flowers = [1,3,1,1], newFlowers = 7, target = 6, full = 12, partial = 1 Output: 14 Explanation: Alice can plant - 2 flowers in the 0th garden - 3 flowers in the 1st garden - 1 flower in the 2nd garden - 1 flower in the 3rd garden The gardens will then be [3,6,2,2]. She planted a total of 2 + 3 + 1 + 1 = 7 flowers. There is 1 garden that is complete. The minimum number of flowers in the incomplete gardens is 2. Thus, the total beauty is 1 * 12 + 2 * 1 = 12 + 2 = 14. No other way of planting flowers can obtain a total beauty higher than 14.
Example 2:
Input: flowers = [2,4,5,3], newFlowers = 10, target = 5, full = 2, partial = 6 Output: 30 Explanation: Alice can plant - 3 flowers in the 0th garden - 0 flowers in the 1st garden - 0 flowers in the 2nd garden - 2 flowers in the 3rd garden The gardens will then be [5,4,5,5]. She planted a total of 3 + 0 + 0 + 2 = 5 flowers. There are 3 gardens that are complete. The minimum number of flowers in the incomplete gardens is 4. Thus, the total beauty is 3 * 2 + 4 * 6 = 6 + 24 = 30. No other way of planting flowers can obtain a total beauty higher than 30. Note that Alice could make all the gardens complete but in this case, she would obtain a lower total beauty.
Constraints:
1 <= flowers.length <= 105
1 <= flowers[i], target <= 105
1 <= newFlowers <= 1010
1 <= full, partial <= 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 method solves this garden beauty problem by trying every single possible combination of how much to grow each garden. We will examine each of these possibilities to identify the arrangement that gives us the highest possible total beauty.
Here's how the algorithm would work step-by-step:
def maximum_total_beauty_brute_force(flowers, new_flowers, target, full, partials):
number_of_gardens = len(flowers)
maximum_beauty = 0
def calculate_beauty(flower_allocation):
total_beauty = 0
full_gardens = 0
for flower_count in flower_allocation:
if flower_count >= target:
total_beauty += full
full_gardens += 1
else:
total_beauty += partials[flower_count]
return total_beauty
def distribute_flowers(garden_index, remaining_new_flowers, flower_allocation):
nonlocal maximum_beauty
if garden_index == number_of_gardens:
# All gardens have been assigned flowers, calculate total beauty.
total_beauty = calculate_beauty(flower_allocation)
maximum_beauty = max(maximum_beauty, total_beauty)
return
# Try all possible flower allocations for the current garden.
max_flowers_for_garden = flowers[garden_index] + remaining_new_flowers
for flowers_to_add in range(remaining_new_flowers + 1):
current_garden_flowers = flowers[garden_index] + flowers_to_add
# Recursive step: move to the next garden.
distribute_flowers(
garden_index + 1,
remaining_new_flowers - flowers_to_add,
flower_allocation + [current_garden_flowers],
)
# Start the flower distribution process from the first garden
distribute_flowers(0, new_flowers, [])
return maximum_beauty
The problem asks us to maximize beauty by strategically upgrading gardens. A key insight is that we can use binary search to efficiently find the optimal beauty threshold. We try to achieve a target beauty and adjust our strategy based on whether it's achievable.
Here's how the algorithm would work step-by-step:
def maximum_beauty(flowers, new_flowers, target, full, partial):
number_of_gardens = len(flowers)
flowers.sort()
prefix_sum = [0] * (number_of_gardens + 1)
for i in range(number_of_gardens):
prefix_sum[i + 1] = prefix_sum[i] + flowers[i]
max_total_beauty = 0
for complete_gardens in range(number_of_gardens + 1):
# Iterate to find optimal number of fully beautified gardens.
remaining_flowers = new_flowers
current_total_beauty = 0
# Attempt to make 'complete_gardens' gardens fully beautiful
flowers_needed = 0
for i in range(number_of_gardens - complete_gardens, number_of_gardens):
flowers_needed += max(0, target - flowers[i])
if flowers_needed <= remaining_flowers:
current_total_beauty += complete_gardens * full
remaining_flowers -= flowers_needed
remaining_gardens = number_of_gardens - complete_gardens
# Binary search to maximize beauty from partial gardens.
if remaining_gardens > 0:
low = 0
high = target - 1
best_base_beauty = 0
while low <= high:
mid = (low + high) // 2
required_flowers = remaining_gardens * mid - (prefix_sum[number_of_gardens - complete_gardens] - prefix_sum[0])
if required_flowers <= remaining_flowers:
best_base_beauty = mid
low = mid + 1
else:
high = mid - 1
current_total_beauty += best_base_beauty * partial
max_total_beauty = max(max_total_beauty, current_total_beauty)
return max_total_beauty
Case | How to Handle |
---|---|
Empty flowers array | If flowers is empty, there are no gardens; return 0 since no beauty can be created. |
newFlowers is 0 | If newFlowers is 0, no flowers can be planted; calculate the beauty based on initial flower counts. |
All flowers are already >= target | If all flowers are already at or above the target, maximize the beauty using full * n. |
target is very large relative to flowers and newFlowers | If target is significantly larger than flowers and newFlowers combined, the optimal strategy might be to focus all newFlowers on one garden. |
full and partial are 0 | If full and partial are zero, the total beauty will always be zero regardless of flower distribution, so return 0. |
Integer overflow when calculating beauty | Use long type to store intermediate and final beauty values to prevent integer overflow. |
newFlowers can make all gardens complete | If newFlowers is large enough to complete all gardens, plant until all gardens have at least target flowers. |
duplicate flower counts in the input array | The solution needs to handle duplicate flower counts correctly during optimization, ensuring not to double-count beauty. |