单调栈的使用场景:通常是一维数组,要寻找任一个元素的右边或者左边第一个比自己大或者小的元素的位置
- 单调栈里存放的元素:元素的下标i,如果需要使用对应的元素,直接T[i]就可以获取。
- 单调栈里元素是递增呢? 还是递减呢?
注意以下讲解中,顺序的描述为 从栈头到栈底的顺序
这里我们要使用递增循序(再强调一下是指从栈头到栈底的顺序),因为只有递增的时候,栈里要加入一个元素i的时候,才知道栈顶元素在数组中右面第一个比栈顶元素大的元素是i。
即:如果求一个元素右边第一个更大元素,单调栈就是递增的,如果求一个元素右边第一个更小元素,单调栈就是递减的。
使用单调栈主要有三个判断条件。
- 当前遍历的元素T[i]小于栈顶元素T[st.top()]的情况
- 当前遍历的元素T[i]等于栈顶元素T[st.top()]的情况
- 当前遍历的元素T[i]大于栈顶元素T[st.top()]的情况
739. 每日温度
class Solution {
public int[] dailyTemperatures(int[] temperatures) {
int len = temperatures.length;
int[] res = new int[len];
Stack<Integer> st = new Stack<>();
st.push(0);
for(int i = 1;i < len;i++){
if(temperatures[i] <= temperatures[st.peek()]){//tem数组写成res数组
st.push(i);
}else{
while(!st.isEmpty() && temperatures[i] > temperatures[st.peek()]){
//与运算写成或运算
res[st.peek()] = i - st.peek();
st.pop();//漏了
}
st.push(i);
}
}
return res;
}
}
496.下一个更大元素 I
用map联系nums1和nums2
class Solution {
public int[] nextGreaterElement(int[] nums1, int[] nums2) {
int[] res = new int[nums1.length];
if(nums1.length == 0)return res;
Arrays.fill(res,-1);
Stack<Integer> st= new Stack<>();
Map<Integer,Integer> map = new HashMap<>();
for(int i = 0;i < nums1.length;i++){
map.put(nums1[i],i);
}
int cnt = 0;
//可有可无
/*
while(!map.containsKey(nums2[cnt])){//containsKey containsValue
cnt++;
}*/
st.push(cnt);
for(int i = cnt + 1;i < nums2.length;i++){
if(nums2[i] <= nums2[st.peek()]){
st.push(i);
}else{
while(!st.isEmpty() && nums2[i] > nums2[st.peek()]){//&&
//用map确认nums1中是否有栈顶元素,有就更新res数组
if(map.containsKey(nums2[st.peek()])){
//用map将nums2下标转到nums1下标
int nums1Index = map.get(nums2[st.peek()]);
res[nums1Index] = nums2[i];
}
st.pop();
}
st.push(i);
}
}
return res;
}
}
503.下一个更大元素II
循环数组通过遍历两遍实现
class Solution {
public int[] nextGreaterElements(int[] nums) {
int[] res = new int[nums.length];
Arrays.fill(res,-1);//忘记填充-1
if(nums.length == 0)return res;
Stack<Integer> st = new Stack<>();
st.push(0);
for(int i = 1;i < nums.length * 2;i++){
if(nums[i % nums.length] <= nums[st.peek()]){
st.push(i % nums.length);
}else{
//感叹号漏了
while(!st.isEmpty() && nums[i % nums.length] > nums[st.peek()]){
res[st.peek()] = nums[i % nums.length];
st.pop();
}
st.push(i % nums.length);
}
}
return res;
}
}

被折叠的 条评论
为什么被折叠?



