代码随想录刷题记录 day51 下一个更大元素II + 接雨水
503. 下一个更大元素 II
思想
和每日温度的思路是一样的,单调栈中存放的是元素的下标,需要学习的是如何模拟遍历两次数组。
for(int i=1;i<nums.length*2;i++){
//这其中所有有关于i的 都用i %nums.length 来表示
}
代码
class Solution {
public int[] nextGreaterElements(int[] nums) {
//循环是怎么考虑的呢?
int[] res=new int[nums.length];
Stack<Integer> stack=new Stack<>();
Arrays.fill(res,-1);
stack.push(0);//stack 存储数组元素的下标
for(int i=1;i<nums.length*2;i++){
if(nums[i%nums.length]<=nums[stack.peek()]){
stack.push(i%nums.length);
}else{
//大于了
while(!stack.empty() && nums[i%nums.length]>nums[stack.peek()]){
res[stack.peek()]=nums[i%nums.length];
stack.pop();
}
stack.push(i%nums.length);
}
}
return res;
}
}
42. 接雨水
思想
方法1:双指针法 按照列来累加,所以所有的宽度都是1
遍历每一个元素,想左去找高度比当前元素高的,想右去找高度比当前元素高的,取其中较矮的那个。
遍历每一个元素 重复次操作
方法2:单调栈 按照行来累加
既然是按照行来累加,那么就 需要得到长宽是多少
栈中存放的是元素的下标
-
数组的元素小于栈顶元素
栈内的元素 从栈底到栈顶应该是从大到小的,遇到小的 直接入栈就好了
-
数组的元素等于栈顶元素
将栈顶元素出栈,新元素入栈,高度相同 计算的是右边的高度
-
数组的元素大于栈顶的元素
数组的元素大于栈顶的元素了 产生了高度差 可以计算雨水了
栈顶的元素 就是左边的高度 height[stack.peek()]
数组的元素 就是右边的高度 height[i]
雨水高度=左右边界较矮的-底部的高度
雨水的宽度=有边界-左边界-1(因为只求中间宽度 所以需要-1)
代码
class Solution {
// public int trap(int[] height) {
// //双指针 按照列为单位来计算
// //每一列的宽度为1
// //高度:当前列的左边 和右边最高的一列 lHeight rHeight
// //取其中最小的
// int res=0;
// for(int i=0;i<height.length;i++){
// if(i==0 || i==height.length-1) continue;//第一列和最后一列不接雨水
// int lHeight=height[i];
// int rHeight=height[i];
// for(int j=i-1;j>=0;j--){
// //向左寻找高度大于当前列的
// if(height[j]>lHeight){
// lHeight=height[j];
// }
// }
// for(int j=i+1;j<height.length;j++){
// //向右寻找高度大于当前列的
// if(height[j]>rHeight){
// rHeight=height[j];
// }
// }
// res+=Math.min(lHeight,rHeight)-height[i];
// }
// return res;
// }
public int trap(int[] height) {
//单调栈
int size=height.length;
int sum=0;
Stack<Integer>stack=new Stack<Integer>();
stack.push(0);
//栈中存放的是元素的下标
//考虑三种情况
//数组的元素小于栈顶元素
//数组的元素等于栈顶元素
//数组的元素大于栈顶的元素
for(int i=1;i<height.length;i++){
if(height[i]<height[stack.peek()]){
//栈内的元素 从栈底到栈顶的数序是从大到小的
stack.push(i);
}else if(height[i]==height[stack.peek()]){
//相等是计算右边的下标
stack.pop();
stack.push(i);
}else{
//数组的元素大于栈顶的元素了 产生了高度差 可以计算雨水了
//栈顶的元素 就是左边的高度 height[stack.peek()]
//数组的元素 就是右边的高度 height[i]
//雨水高度=左右边界较矮的-底部的高度
//雨水的宽度=有边界-左边界-1(因为只求中间宽度 所以需要-1)
while(!stack.empty() && height[i]>height[stack.peek()]){
//为什么是while 如果是 3 2 1 4
//会计算两行的雨水量
int mid=stack.peek();//表示凹槽底部
stack.pop();
if(!stack.empty()){
int h=Math.min(height[stack.peek()],height[i])-height[mid];
int w=i-stack.peek()-1;
sum+=h*w;
}
}
stack.push(i);
}
}
return sum;
}
}