1. 下一个更大元素II
503. 下一个更大元素 II - 力扣(LeetCode)
循环数组,就可以遍历两遍,i 对数组长度取余即可表示第二遍的真实下标
其余的一样,维护一个单调递减(等于)的栈即可
class Solution {
public int[] nextGreaterElements(int[] nums) {
Stack<Integer> stack = new Stack<>();
int length = nums.length;
int[] next = new int[length];
Arrays.fill(next, -1);
for(int i = 0; i < 2*length; i++){
while(!stack.isEmpty() && nums[i%length] > nums[stack.peek()]){
next[stack.peek()] = nums[i%length];
stack.pop();
}
stack.push(i%length);
}
return next;
}
}
2. 接雨水
本质还是维护一个单调栈(递减或等于)
当前元素大于栈顶,说明找到了前一个元素的左边第一个最大值,
而前一个元素的右边第一个最大值就是它的前一个(因为栈递减)
两边的值取最小值再减去中间的值,雨水的高度就有了(横向)
雨水的底就是左右两边的空隙
class Solution {
public int trap(int[] height) {
int res = 0;
Stack<Integer> stack = new Stack<>();// 递减
for(int i = 0; i < height.length; i++){
while(!stack.isEmpty() && height[i] > height[stack.peek()]){
int mid = stack.pop();
if(!stack.isEmpty()){
// 右边第一个大,左边第一个大,最小的那个减去中间的高度差,就是雨水的高度
int h = Math.min(height[i], height[stack.peek()]) - height[mid];
// 高度 * 底的长度
res += h * (i - stack.peek() - 1);
}
}
stack.push(i);
}
return res;
}
}
横向求得雨水面积