leetcode
leetcode 2451 ~ 2500
美丽塔 I

美丽塔 I

难度:

标签:

题目描述

You are given a 0-indexed array maxHeights of n integers.

You are tasked with building n towers in the coordinate line. The ith tower is built at coordinate i and has a height of heights[i].

A configuration of towers is beautiful if the following conditions hold:

  1. 1 <= heights[i] <= maxHeights[i]
  2. heights is a mountain array.

Array heights is a mountain if there exists an index i such that:

  • For all 0 < j <= i, heights[j - 1] <= heights[j]
  • For all i <= k < n - 1, heights[k + 1] <= heights[k]

Return the maximum possible sum of heights of a beautiful configuration of towers.

 

Example 1:

Input: maxHeights = [5,3,4,1,1]
Output: 13
Explanation: One beautiful configuration with a maximum sum is heights = [5,3,3,1,1]. This configuration is beautiful since:
- 1 <= heights[i] <= maxHeights[i]  
- heights is a mountain of peak i = 0.
It can be shown that there exists no other beautiful configuration with a sum of heights greater than 13.

Example 2:

Input: maxHeights = [6,5,3,9,2,7]
Output: 22
Explanation: One beautiful configuration with a maximum sum is heights = [3,3,3,9,2,2]. This configuration is beautiful since:
- 1 <= heights[i] <= maxHeights[i]
- heights is a mountain of peak i = 3.
It can be shown that there exists no other beautiful configuration with a sum of heights greater than 22.

Example 3:

Input: maxHeights = [3,2,5,5,2,3]
Output: 18
Explanation: One beautiful configuration with a maximum sum is heights = [2,2,5,5,2,2]. This configuration is beautiful since:
- 1 <= heights[i] <= maxHeights[i]
- heights is a mountain of peak i = 2. 
Note that, for this configuration, i = 3 can also be considered a peak.
It can be shown that there exists no other beautiful configuration with a sum of heights greater than 18.

 

Constraints:

  • 1 <= n == maxHeights <= 103
  • 1 <= maxHeights[i] <= 109

代码结果

运行时间: 41 ms, 内存: 16.4 MB


/*
 思路:
 1. 找到峰值位置。
 2. 使用Stream从峰值位置向两边递减构建山脉数组。
 3. 计算山脉数组的高度和。
 */
import java.util.stream.IntStream;
import java.util.Arrays;

public class BeautifulTowersStream {
    public int maxBeautifulTowers(int[] maxHeights) {
        int n = maxHeights.length;
        int peak = IntStream.range(0, n)
                            .boxed()
                            .max((i, j) -> Integer.compare(maxHeights[i], maxHeights[j]))
                            .get();
        int[] heights = new int[n];
        heights[peak] = maxHeights[peak];
        IntStream.range(0, peak)
                 .map(i -> peak - i - 1)
                 .forEach(i -> heights[i] = Math.min(heights[i + 1], maxHeights[i]));
        IntStream.range(peak + 1, n)
                 .forEach(i -> heights[i] = Math.min(heights[i - 1], maxHeights[i]));
        return Arrays.stream(heights).sum();
    }
}

解释

方法:

此题解尝试寻找最大的可能的山脉数组`heights`的高度总和。对于每个可能的山脉顶点`i`,它首先将`heights[i]`设置为`maxHeights[i]`的最大值,并且从顶点向两侧扩展。向左和向右扩展时,确保山脉的高度不增加,即对于左侧的任何`j < i`,有`heights[j] <= heights[j + 1]`,对于右侧的任何`j > i`,有`heights[j] <= heights[j - 1]`。通过遍历每个元素,尝试将其作为山脉顶点,并计算可能的最大高度和。如果当前构造的山脉高度和超过之前记录的最大值,则更新最大值。

时间复杂度:

O(n^2)

空间复杂度:

O(1)

代码细节讲解

🦆
算法如何确保在每个方向上,即使存在高度较低的塔,也能构建出最大的山脉总和?
算法通过从山顶开始,向左右两侧逐步构建山脉,确保高度不增加。对于每个方向,算法始终尝试将当前高度与前一个高度(从山顶开始)进行比较。如果当前高度小于或等于前一个高度,则当前高度被添加到总和中,这样确保能构建一个符合山脉形状的数组。如果当前高度大于前一个高度,则使用前一个高度的值,这样可以避免山脉的高度突然增加,保持了山脉的递减性质。这种策略确保了即使在高度较低的塔存在时也能获得可能的最大山脉总和。
🦆
在构建山脉的过程中,如果`maxHeights`数组中存在连续几个极小值,这种情况下算法的表现如何?
如果`maxHeights`数组中存在连续的极小值,这些值会限制山脉高度的增加,特别是在这些极小值区域的山脉顶部附近。算法会通过使用这些极小值作为高度,向左右扩展时维持高度不超过这些值。这可能导致在这些区域的山脉总和不是最大可能值。然而,算法通过尝试不同的山脉顶点位置来找到可能的最大总和,这意味着在某些情况下,尽管存在极小值区域,但选择其他位置作为山顶可能会产生更大的总和。
🦆
为什么选择将`maxHeights[i]`直接设为山顶,而不是从更低的值开始递增尝试是否能达到更高的总和?
选择`maxHeights[i]`作为山顶是因为这提供了从每个可能的山顶位置获取最大高度的直接方式,从而最大化山脉总和的可能性。从更低的值开始递增虽然理论上可以探索更多可能的山脉形状,但实际上这会大大增加算法的复杂性和运行时间,因为需要对每个位置考虑多种高度。直接使用`maxHeights[i]`作为山顶简化了问题,使得算法只需要关注如何有效地从这一最高点向两侧扩展,以构建符合条件的最大山脉总和。

相关问题