leetcode
leetcode 2451 ~ 2500
美丽塔 II

美丽塔 II

难度:

标签:

题目描述

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 <= 105
  • 1 <= maxHeights[i] <= 109

代码结果

运行时间: 227 ms, 内存: 39.9 MB


/*
 * 思路:
 * 1. 寻找每一个位置作为峰值的最大山脉数组
 * 2. 对每一个位置,向左和向右遍历,找到符合条件的最大高度
 * 3. 计算每一个位置作为峰值时的高度和,取最大值
 */
import java.util.stream.IntStream;

public class BeautifulTowersStream {
    public int maxSumOfHeights(int[] maxHeights) {
        int n = maxHeights.length;

        return IntStream.range(0, n)
            .map(i -> {
                int[] heights = new int[n];
                heights[i] = maxHeights[i];

                IntStream.rangeClosed(0, i - 1)
                    .forEach(j -> heights[j] = Math.min(maxHeights[j], heights[j + 1]));
                IntStream.range(i + 1, n)
                    .forEach(j -> heights[j] = Math.min(maxHeights[j], heights[j - 1]));

                return IntStream.of(heights).sum();
            })
            .max()
            .orElse(0);
    }

    public static void main(String[] args) {
        BeautifulTowersStream solution = new BeautifulTowersStream();
        int[] maxHeights = {6, 5, 3, 9, 2, 7};
        System.out.println(solution.maxSumOfHeights(maxHeights)); // 22
    }
}

解释

方法:

The given solution tries to find the maximum sum of heights for a mountain array configuration. First, it uses two arrays `pre` and `post` to store the maximum possible sum of heights from the start to the current index (for `pre`) and from the current index to the end (for `post`). The algorithm performs two passes over the `maxHeights` array. In the first pass (forward direction), it computes for each tower the maximum sum of heights from the start up to and including that tower, under the constraint that tower heights must not decrease. It uses a stack to maintain indices of towers such that the heights at these indices are in a non-decreasing order. This helps in efficiently computing the range sum by popping indices from the stack when the current tower height is less than the height at the top index of the stack. In the second pass (backward direction), it similarly computes the maximum sum of heights from each tower to the end of the array. Finally, for each tower, it combines these sums (subtracting the tower's height once because it's added in both `pre` and `post`), and tracks the maximum sum obtained. This maximum sum represents the highest sum of heights for a mountain array configuration.

时间复杂度:

O(n)

空间复杂度:

O(n)

代码细节讲解

🦆
你是如何确定双指针是解决这个问题的最佳方法?
在题解中,并没有使用双指针技术;而是采用了单调栈来维护一个非递减序列的索引。这种方法适用于需要快速计算区间最大值或相关统计量的场景,以及在本题中,用于高效地计算每个位置的山脉数组可能的最大高度总和。单调栈可以在一次遍历中处理和维护需要的索引顺序,从而使得计算前缀和后缀时更为高效。
🦆
在进行前向遍历和后向遍历时,为什么选择使用堆栈来维护非递减序列的索引?
使用堆栈(栈)来维护一个非递减序列的索引,是因为栈具有后进先出(LIFO)的特性,这使得我们可以在遍历数组的过程中,方便地添加或移除元素以维持序列的非递减性。在前向遍历中,如果当前元素小于栈顶元素,就需要移除栈顶元素,保证栈内始终是非递减的;这样可以保证在每个位置计算最大高度总和时,都能快速地获取到需要的最小元素。这种方法提高了效率,避免了重复的比较和计算。
🦆
在计算`pre[i]`和`post[i]`时,若当前索引对应的高度低于栈顶索引对应的高度时,为什么直接将栈顶元素弹出?这样做有何优势?
当当前索引对应的高度低于栈顶索引对应的高度时,直接将栈顶元素弹出,是因为栈顶的高度已经无法用于构建一个有效的山脉形态(即在这一点之后高度需要递减)。通过弹出更高的栈顶元素,我们能更新栈以保证只包含可以用来维持山脉数组性质的元素。这样做的优势在于可以确保在每个位置的高度计算都符合山脉数组的要求,同时避免无效的高度值影响最终的计算结果,从而提高算法的正确性和效率。

相关问题