最大宽度坡
难度:
标签:
题目描述
代码结果
运行时间: 45 ms, 内存: 21.6 MB
/*
* 思路:
* 1. 使用Stream API处理数组A,利用stack辅助进行递减序列的维护。
* 2. 使用stream进行遍历时,需要先从右到左找到最大的坡宽度。
* 3. 最终结果使用Optional来处理,确保无坡时返回0。
*/
import java.util.*;
import java.util.stream.*;
public class MaxWidthRampStream {
public int maxWidthRamp(int[] A) {
Deque<Integer> stack = new LinkedList<>();
IntStream.range(0, A.length).forEach(i -> {
if (stack.isEmpty() || A[stack.peek()] > A[i]) {
stack.push(i);
}
});
OptionalInt maxWidth = IntStream.range(0, A.length)
.mapToObj(j -> new int[] {j})
.sorted((a, b) -> b[0] - a[0])
.flatMapToInt(jArr -> {
int j = jArr[0];
int[] max = {0};
while (!stack.isEmpty() && A[stack.peek()] <= A[j]) {
max[0] = Math.max(max[0], j - stack.pop());
}
return IntStream.of(max[0]);
})
.max();
return maxWidth.orElse(0);
}
}
解释
方法:
该题解采用单调栈的方法来求解最大宽度坡问题。首先,构建一个单调递减栈,栈中存储数组元素的索引,确保栈中的元素对应的数组值是递减的。这样做的目的是为了后面从数组尾部开始向前遍历时,能快速找到满足条件的坡底(即数组中较小的值)。在遍历过程中,对于每个元素,试图找到一个坡底,使得坡底的值不大于当前元素的值。如果找到了这样的坡底,那么计算当前的宽度(当前索引减去坡底索引),并更新最大宽度。重复这个过程直到遍历完数组或栈为空。
时间复杂度:
O(n)
空间复杂度:
O(n)
代码细节讲解
🦆
为什么在构建单调递减栈时,只有当当前元素小于栈顶元素时才将其索引入栈?
▷🦆
在从后向前遍历数组时,为什么要检查当前元素是否大于等于栈顶元素对应的值?
▷🦆
在最后向后遍历数组计算最大宽度时,弹出栈顶元素的条件是什么?为什么选择这样的条件?
▷🦆
如果数组中包含重复元素,单调栈方法是否仍然有效?会有哪些特别的情况需要考虑?
▷