前言
前面我们说到了单调栈的第一题,下一个最大元素I,其实今天的两道题都是对他的变种,知道第一个单调栈的思想能够想清楚,其实这道题是很简单的
考虑好三个状态,大于等于小于,其实对于前面这些题目只要细心的小伙伴就会发现其实小于和等于的处理是一样的都是直接入栈,只有大于的才会将栈头一直出栈,最后将该元素入栈.
LeetCode T503 下一个最大元素II
题目链接:503. 下一个更大元素 II - 力扣(LeetCode)
题目思路:
这题的题目思路其实和上一题差不多,都是单调栈的经典例题,这题其实也就是在上一题的基础上加上了可以循环地搜索,其实我们只需要遍历两次数组即可,第一次的最大元素在单调栈
中保存了,第二次再遍历的时候就能达到循环搜索的效果了
这里贴上昨天单调栈的原版的思路链接:
代码和思路基本一样,这里不做过多赘述
代码随想录 Day49 单调栈01 LeetCode LeetCodeT739每日温度 T496 下一个最大元素I-CSDN博客
题目代码:
class Solution {
public int[] nextGreaterElements(int[] nums) {
int[] res = new int[nums.length];
Arrays.fill(res,-1);
Stack<Integer> st = new Stack<>();
st.push(0);
for(int i = 0;i<2*nums.length;i++){
int k = i%nums.length;
if(nums[k]<=nums[st.peek()]){
st.push(k);
}else{
while(!st.isEmpty() && nums[k]>nums[st.peek()]){
res[st.peek()] = nums[k];
st.pop();
}
st.push(k);
}
}
return res;
}
}
LeetCode T42 接雨水
题目链接:42. 接雨水 - 力扣(LeetCode)
题目思路:
首先明确单调栈是这样计算雨水的,横向计算而不是竖向计算
下面我们考虑递减栈还是递增栈
明显是递增栈,我们需要找到前一个比他大的元素和后一个比他大的元素
因为一旦发现添加的柱子高度大于栈头元素了,此时就出现凹槽了,栈头元素就是凹槽底部的柱子,栈头第二个元素就是凹槽左边的柱子,而添加的元素就是凹槽右边的柱子。
如果遇到相同元素的怎么办??
此时选择弹出第一个相同元素或者不弹出其实都一样
弹出就是只计算一次,
不弹出的话第一次计算完中间高度就会变成5了
右边只要能找到一个大于5的,这样5就是最小值
然后计算高度的时候5减去中间柱子5就变成0了,也就等于没计算
只是计算方式不一样而已
使用宽*高来计算,最后相加就行
.
.
.
.
题目代码:
class Solution {
public int trap(int[] height) {
if(height.length<=2){
return 0;
}
int sum = 0;
Stack<Integer> st = new Stack<>();
st.push(0);
for(int i = 1;i<height.length;i++){
if(height[i]<=height[st.peek()]){
st.push(i);
}else{
while(!st.isEmpty() && height[i]>height[st.peek()]){
int tmp = st.peek();
st.pop();
if(!st.isEmpty()){
int h = Math.min(height[i],height[st.peek()])-height[tmp];
int w = i-st.peek()-1;
sum += h*w;
}
}
st.push(i);
}
}
return sum;
}
}