题目1:下一个更大元素II
- 题目链接:
1- 思路
模式理解:
- 模式1:下一个更大 ——> 单调栈
- 模式2:环形数组 ——> 取模代替成环的过程
思路
1- 数据结构
- 创建单调栈
- 结果集 int 数组
2- 遍历环形数组,利用 2*len 取模实现
- **2-1 遍历:**i 从 1 遍历到 2*len
- 2-2 当前元素 <= 栈顶:此时入栈即可
- 2-3 当前元素 > 栈顶:收集结果
- 利用 while 两个条件来一直收集结果 ①st不为空、②当前元素大于栈顶
- 收集结果
- st 进行 pop
2- 题解
⭐ 下一个更大元素 II——题解思路
class Solution {
public int[] nextGreaterElements(int[] nums) {
// 1. 数据结构
int len = nums.length;
int[] res = new int[len];
Arrays.fill(res,-1);
// 2. 单调栈
Stack<Integer> st = new Stack<>();
st.push(0);
for(int i = 1 ; i < len*2 ;i++){
// 小于等于
if(nums[i%len]<= nums[st.peek()]){
st.push(i%len);
}else{
while(!st.isEmpty() && nums[i%len] > nums[st.peek()]){
res[st.peek()] = nums[i%len];
st.pop();
}
st.push(i%len);
}
}
return res;
}
}
题目2:42. 接雨水
- 题目链接:42. 接雨水
1- 思路
利用单调栈,在当前元素大于栈顶元素的时候收集结果
- 即
nums[i] > nums[st.peek()]
时 收集结果 - 收集结果思路:当前元素大,证明是凹槽的右侧 第一高的元素,找到凹槽左侧比凹槽高的柱子即可,也就是栈中第二个柱子的高度
- ① 获取中间元素
mid = st.pop()
——> ② 此时st.peek()
就是左侧高的柱子 ;nums[i]
为右侧高柱子;当前元素为 nums[mid] - ——> ③ 处理逻辑
h = Math.min(st.peek(),nums[mid])
- ——>
width = i - st.peek() - 1
- ——> 面积为
h * width
** 实现思路**
- 1- 数据结构
- 结果数组:
int res = 0
- 单调栈:
Stack<Integer> st = new Stack<>()
,初始化填入0
- 结果数组:
- 2- 遍历
- 2-1 遍历顺序:
i
从1
遍历到nums.length
- 2-2 当前元素 <= st.peek(): 直接入栈
- 2-3 当前元素 > st.peek() :处理逻辑
- 右侧高柱子:当前元素为
- 凹槽元素:定义
mid
获取当前st.pop()
为凹槽元素 - 左侧高元素:
st.peek()
为左侧高元素 height = Math.min(height[left], height[i]) - height[mid]
width = i - st.peek - 1
- 结果收集:
res+= height * width
- 2-1 遍历顺序:
2- 题解
⭐ 接雨水 ——题解思路
class Solution {
public int trap(int[] height) {
// 数据结构
int len = height.length;
int res = 0;
Stack<Integer> st = new Stack<>();
st.push(0);
// 遍历
for(int i = 1 ; i < len ;i++){
if(height[i] <= height[st.peek()]){
st.push(i);
}else{
while(!st.isEmpty() && height[i] > height[st.peek()]){
int mid = st.pop();
if(!st.isEmpty()){
int left = st.peek();
int h = Math.min(height[left],height[i])-height[mid];
int w = i - left -1;
int hold = h*w;
if(hold>0){
res+=hold;
}
}
}
st.push(i);
}
}
return res;
}
}