代码随想录打卡第39天:单调栈

1.单调栈

1.什么是单调栈?

单调栈的本质是空间换时间,因为在遍历的过程中需要用一个栈来记录右边第一个比当前元素高的元素,优点是整个数组只需要遍历一次。

2.单调栈一般解决什么问题?

通常是一维数组,要寻找任一个元素的右边或者左边第一个比自己大或者小的元素的位置,此时我们就要想到可以用单调栈了。时间复杂度为O(n)。

3.单调栈需要考虑什么?

  1. 单调栈里存放的元素是什么?单调栈里只需要存放元素的下标i就可以了,如果需要使用对应的元素,直接T[i]就可以获取。
  2. 单调栈里元素是递增呢? 还是递减呢?

4.单调栈需要判断的条件

  • 当前遍历的元素T[i]小于栈顶元素T[st.top()]的情况
  • 当前遍历的元素T[i]等于栈顶元素T[st.top()]的情况
  • 当前遍历的元素T[i]大于栈顶元素T[st.top()]的情况

2.739每日温度

1.解题思路

由于题目中需要找到右边第一个比今天大的温度,与单调栈的思路相匹配,所以本题使用单调栈来解决问题。

2.具体实现

st存放的是顺序遍历时还未找到右边第一个比今天大的温度。

ret存放的是对应的右边第一个比今天大的温度数组,默认情况下全为-1。

  • 当前遍历的元素T[i]小于栈顶元素T[st.top()]的情况,没有找到右边的大于的元素,直接入栈
  • 当前遍历的元素T[i]等于栈顶元素T[st.top()]的情况,没有找到右边的大于的元素,直接入栈
  • 当前遍历的元素T[i]大于栈顶元素T[st.top()]的情况,找到了右边的大于的元素,出栈放到对应下标位置的ret,继续判断,直到遇到不大于的元素之后结束出栈操作,然后将当前值入栈
  • 由前面的可以看出,这个st存放的是一个单调递减的。
  • while(!st.empty()&&temperatures[st.top()] < temperatures[i]){
                        ret[st.top()] = i - st.top();
                        //cout<<st.top()<<i-st.top()<<endl;
                        st.pop();
                    }
                    st.push(i);

3.具体代码

class Solution {
public:
    vector<int> dailyTemperatures(vector<int>& temperatures) {
        stack<int> st;//存放的是下标
        int n = temperatures.size();
        vector<int> ret(n,0);
        st.push(0);
        for(int i = 1;i<n;i++){
            //cout<<st.top()<<temperatures[st.top()]<<i-st.top()<<endl;
            if(temperatures[st.top()]>temperatures[i]){
                st.push(i);
            }else if(temperatures[st.top()]== temperatures[i]){
                st.push(i);
            }else{
                while(!st.empty()&&temperatures[st.top()] < temperatures[i]){
                    ret[st.top()] = i - st.top();
                    //cout<<st.top()<<i-st.top()<<endl;
                    st.pop();
                }
                st.push(i);
            }
        }
        return ret;
    }
};

  • 5
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值