503.下一个更大元素II
这道题和 739. 每日温度 几乎如出一辙,可以自己尝试做一做
class Solution {
public int[] nextGreaterElements(int[] nums) {
int[] res=new int[nums.length];
Deque<Integer> stack=new LinkedList<>();
Arrays.fill(res,-1);
stack.push(0);
//模拟循环加长二倍,最后取前三位
for(int i=1;i<nums.length*2;i++){
//stack装的是nums2的下标!!!
int index=i%nums.length;
//nums[index]相当于当前元素
//如果到第二次循环,因为第一次循环已经更新过res结果集了,所以第二次循环的结果集元素只是会放入栈中并不会对结果集造成影响。(在就循环一次的情况下最后一个元素放入栈中,res对应位置为默认值-1)
if(nums[index]<=nums[stack.peek()]){
stack.push(index);
}else{
while(!stack.isEmpty()&&nums[index]>nums[stack.peek()]){
res[stack.peek()]=nums[index];
stack.pop();
}
stack.push(index);
}
}
return res;
}
}
42.接雨水
接雨水这道题目是 面试中特别高频的一道题,也是单调栈 应用的题目,大家好好做做。
建议是掌握 双指针 和单调栈,因为在面试中 写出单调栈可能 有点难度,但双指针思路更直接一些。
在时间紧张的情况有,能写出双指针法也是不错的,然后可以和面试官在慢慢讨论如何优化。
class Solution {
public int trap(int[] height) {
//队头作为mid 然后寻找其右面最大(之后添加进来的元素)以及左面最大(以前添加的第一个最大的元素)
//栈内递增序列(入栈一个比一个小)
Deque<Integer> stack=new LinkedList<>();
int res=0;
stack.push(0);//放入第一个元素下标
//遍历并放入
for(int i=1;i<height.length;i++){
//如果遍历到的比对头要小就入栈
if(height[i]<=height[stack.peek()]){//形成单调放入栈中
stack.push(i);
}else{
//碰到比栈口大的就进行处理 不入栈
//不断弹出队头直到找到队头元素比当前height[i]大
//因为while内要做弹出操作所以要判断stack.isEmpty()不为空
while(!stack.isEmpty()&&height[i]>height[stack.peek()]){
int mid=stack.pop();
int right=i;
//因为之前pop出去了 还要判断是否为空,不为空才能peek
if(!stack.isEmpty()){
int left=stack.peek();
int width=right-left-1;
int h=Math.min(height[right],height[left])-height[mid];
if (h*width > 0)res+=h*width;
}
}
stack.push(i);
}
}
return res;
}
}