提示:努力生活,开心、快乐的一天
文章目录
- [503. 下一个更大元素 II](#503. 下一个更大元素 II)
- [42. 接雨水](#42. 接雨水)
- 🎈今日心得
503. 下一个更大元素 II
💡解题思路
- 这道题和739. 每日温度 (opens new window)也几乎如出一辙。不过,本题要循环数组了。
- 循环数组:在遍历的过程中模拟走了两边nums
🤔遇到的问题
- 如何循环数组
💻代码实现
js
var nextGreaterElements = function (nums) {
const len = nums.length;
let stack = [];
let res = Array(len).fill(-1);
for (let i = 0; i < len * 2; i++) {
// 模拟遍历两边nums,注意一下都是用i % nums.size()来操作
while (
stack.length &&
nums[i % len] > nums[stack[stack.length - 1]]
) {
const index = stack.pop();
res[index] = nums[i % len];
}
stack.push(i % len);
}
return res;
};
[left,right)
🎯题目总结
- 与美日温度几乎一样
42. 接雨水
💡解题思路
- 首先单调栈是按照行方向来计算雨水,如图:
- 使用单调栈内元素的顺序
从栈头(元素从栈头弹出)到栈底的顺序应该是从小到大的顺序。
因为一旦发现添加的柱子高度大于栈头元素了,此时就出现凹槽了,栈头元素就是凹槽底部的柱子,栈头第二个元素就是凹槽左边的柱子,而添加的元素就是凹槽右边的柱子 - 遇到相同高度的柱子怎么办
遇到相同的元素,更新栈内下标,就是将栈里元素(旧下标)弹出,将新元素(新下标)加入栈中。例如 5 5 1 3 这种情况。如果添加第二个5的时候就应该将第一个5的下标弹出,把第二个5添加到栈中。因为我们要求宽度的时候 如果遇到相同高度的柱子,需要使用最右边的柱子来计算宽度。 - 栈里要保存什么数值
使用单调栈,也是通过 长 * 宽 来计算雨水面积的。
长就是通过柱子的高度来计算,宽是通过柱子之间的下标来计算,
那么栈里有没有必要存一个pair<int, int>类型的元素,保存柱子的高度和下标呢。
其实不用,栈里就存放下标就行,想要知道对应的高度,通过height[stack.top()] 就知道弹出的下标对应的高度了。
🤔遇到的问题
- 逻辑还是有点乱
💻代码实现
js
var trap = function(height) {
const len = height.length;
if(len <= 2) return 0; // 可以不加
const st = [];// 存着下标,计算的时候用下标对应的柱子高度
st.push(0);
let sum = 0;
for(let i = 1; i < len; i++){ // 只处理的情况三,其实是把情况一和情况二融合了
while (st.length !== 0 && height[i] > height[st[st.length - 1]]) { // 注意这里是while
let mid = st[st.length - 1];
st.pop();
if (st.length !== 0) {
let h = Math.min(height[st[st.length - 1]], height[i]) - height[mid];
let w = i - st[st.length - 1] - 1; // 注意减一,只求中间宽度
sum += h * w;
}
}
st.push(i);
}
return sum;
};
🎯题目总结
单调栈处理逻辑:
以下逻辑主要就是三种情况
情况一:当前遍历的元素(柱子)高度小于栈顶元素的高度 height[i] < height[st.top()]
情况二:当前遍历的元素(柱子)高度等于栈顶元素的高度 height[i] == height[st.top()]
情况三:当前遍历的元素(柱子)高度大于栈顶元素的高度 height[i] > height[st.top()]
🎈今日心得
单调栈,好难的