You are given an array heights
of n
integers representing the number of bricks in n
consecutive towers. Your task is to remove some bricks to form a mountain-shaped tower arrangement. In this arrangement, the tower heights are non-decreasing, reaching a maximum peak value with one or multiple consecutive towers and then non-increasing.
Return the maximum possible sum of heights of a mountain-shaped tower arrangement.
Example 1:
Input: heights = [5,3,4,1,1]
Output: 13
Explanation:
We remove some bricks to make heights = [5,3,3,1,1]
, the peak is at index 0.
Example 2:
Input: heights = [6,5,3,9,2,7]
Output: 22
Explanation:
We remove some bricks to make heights = [3,3,3,9,2,2]
, the peak is at index 3.
Example 3:
Input: heights = [3,2,5,5,2,3]
Output: 18
Explanation:
We remove some bricks to make heights = [2,2,5,5,2,2]
, the peak is at index 2 or 3.
Constraints:
1 <= n == heights.length <= 103
1 <= heights[i] <= 109
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 to this tower problem is simple: try every single possible tower configuration. Calculate the total beauty of each possible tower and keep track of the best one we've seen so far. By checking absolutely every option, we are guaranteed to find the most beautiful tower.
Here's how the algorithm would work step-by-step:
def beautiful_towers_brute_force(max_heights):
number_of_towers = len(max_heights)
max_beauty = 0
for peak_index in range(number_of_towers):
# Iterate through each index and treat it as the peak
current_tower = [0] * number_of_towers
current_tower[peak_index] = max_heights[peak_index]
# Build to the left of the peak
for left_index in range(peak_index - 1, -1, -1):
current_tower[left_index] = min(max_heights[left_index], current_tower[left_index + 1])
# Build to the right of the peak
for right_index in range(peak_index + 1, number_of_towers):
current_tower[right_index] = min(max_heights[right_index], current_tower[right_index - 1])
tower_beauty = sum(current_tower)
# Update max beauty if necessary
if tower_beauty > max_beauty:
max_beauty = tower_beauty
return max_beauty
The trick to efficiently solving this problem is to consider each possible tower location as the tallest point and build outwards. For each potential tallest tower, we expand to the left and right, lowering the tower heights as necessary to meet the problem's constraints.
Here's how the algorithm would work step-by-step:
def beautiful_towers_i(maximum_heights):
number_of_towers = len(maximum_heights)
max_sum_heights = 0
for tallest_tower_index in range(number_of_towers):
tower_heights = [0] * number_of_towers
tower_heights[tallest_tower_index] = maximum_heights[tallest_tower_index]
current_sum_heights = tower_heights[tallest_tower_index]
# Build to the left of the tallest tower.
left_index = tallest_tower_index - 1
while left_index >= 0:
# Ensure the current tower is no taller than the tower to its right
tower_heights[left_index] = min(maximum_heights[left_index], tower_heights[left_index + 1])
current_sum_heights += tower_heights[left_index]
left_index -= 1
# Build to the right of the tallest tower.
right_index = tallest_tower_index + 1
while right_index < number_of_towers:
# Ensure the current tower is no taller than the tower to its left
tower_heights[right_index] = min(maximum_heights[right_index], tower_heights[right_index - 1])
current_sum_heights += tower_heights[right_index]
right_index += 1
# Keep track of the largest sum found.
max_sum_heights = max(max_sum_heights, current_sum_heights)
return max_sum_heights
Case | How to Handle |
---|---|
Empty heights array | Return 0 immediately as there are no towers to build. |
Single element heights array | Return the value of the single element since it's a valid beautiful tower. |
All heights are the same | The resulting beautiful tower will also have all heights the same, equal to the input height, and sum calculation will work as expected. |
Heights array is strictly increasing | The maximum height will be the last element, and no modification is needed. |
Heights array is strictly decreasing | The beautiful tower will be strictly decreasing as well, ending with height 1. |
Heights array contains large numbers, potential for integer overflow when calculating the sum | Use a 64-bit integer type (long) to store the sum of the beautiful tower to avoid overflow. |
Heights array with the maximum size allowed by the problem constraints | Ensure the chosen algorithm has a time complexity that is efficient enough to handle the maximum input size, ideally O(n) or O(n log n). |
heights[i] is zero | The beautiful tower can include zero as one of its element and the solution should correctly compute the sum based on the given heights array. |