单调队列经典题目(c++)

 单调栈专门解决Next Greater Number

739. 每日温度

动画理解

本题是将后续温度的索引存入栈中,这样可以直接通过temp[st.top()]来查询到温度的值,就相当于变相的map容器 

class Solution {
    //温度索引存入单调队列
public:
    vector<int> dailyTemperatures(vector<int>& temp) {
        vector<int>answer(temp.size(),0);//将其全赋为0
        deque<int>dq;//单调队列的元素从队首到队尾值依次递减。如果碰到了更大的温度,则将队尾元素弹出
        for(int i=0;i<temp.size();++i){
            while(!dq.empty()&&temp[i]>temp[dq.back()]){//如果下一天温度更高
                int value=dq.back();//将队尾元素存入value
                answer[value]=i-value;//当前更高的温度的索引减去队尾温度索引的值,就是他俩的间隔天数
                dq.pop_back();//弹出队尾元素
            }
        dq.push_back(i);//将当前温度索引存入队列
        }
    return answer;
    }
};

!dq.empty()判断队列是否为空很重要!

class Solution {
    //温度索引存入单调队列
public:
    vector<int> dailyTemperatures(vector<int>& temp) {
        vector<int>answer(temp.size(),0);//将其全赋为0
        stack<int>st;//单调队列的元素从栈底到栈顶值依次递减。如果碰到了更大的温度,则将栈顶元素弹出
        for(int i=0;i<temp.size();++i){
            while(!st.empty()&&temp[i]>temp[st.top()]){//如果下一天温度更高
                int value=st.top();//将栈顶元素存入value
                answer[value]=i-value;//当前更高的温度的索引减去栈顶温度索引的值,就是他俩的间隔天数
                st.pop();//弹出栈顶元素
            }
            if(st.empty()||temp[i]<=temp[st.top()])//如果下一天温度更低或者栈空
                st.push(i);//将当前温度索引存入栈
        }
    return answer;
    }
};

496. 下一个更大元素 I

将元素的值压入栈,通过比较值大小,进而实现栈的增或减

class Solution {
public:
    vector<int> nextGreaterElement(vector<int>& nums1, vector<int>& nums2) {
        //将map(key)设为nums2[i],map(value)存放下一个更大元素
        //这样可以得到nums2中每个元素的下一个更大元素的值,再通过nums1在mp中查找即可
        unordered_map<int,int>mp;//将温度赋给value,索引赋给key
        vector<int>result(nums1.size(),-1);//存放最终返回结果
        stack<int>st;//先将nums2的元素索引存入栈,如果有更大的元素,则存入数组
        st.push(nums2[0]);//先存入第一个元素

        for(int i=0;i<nums2.size();i++){
            mp[nums2[i]]=-1;//默认value都是-1
        }
        for(int i=1;i<nums2.size();i++){
            while(!st.empty()&&nums2[i]>st.top()){//如果下一个元素更大
                mp[st.top()]=nums2[i];//将更大的那个元素存入value
                st.pop();
            }
            if(st.empty()||nums2[i]<=st.top())//如果下一个元素更小
                st.push(nums2[i]);入栈
        }

        for(int i=0;i<nums1.size();i++){//遍历nums1的元素,通过mp[nums1[i]]可得到下一个更大元素
            result[i]=mp[nums1[i]];
        }
    return result;
    }
};

503. 下一个更大元素 II

将元素索引压入栈,通过遍历索引,进而实现栈的增或减

class Solution {
public:
    vector<int> nextGreaterElements(vector<int>& nums) {
        //实例2中nums = [1,2,3,4,3]输出: [2,3,4,-1,4],可以理解为nums的
        //第一个元素对应2,第二个元素对应3,第三个元素对应4,以此类推。所以
        //通过该题通过用单调栈排列索引来实现。与下一个更大元素 I有不同
        stack<int>st;
        vector<int>result(nums.size(),-1);
        for(int i=0;i<2*nums.size();i++){
            int j=i%nums.size();
            while(!st.empty()&&nums[j]>nums[st.top()]){//如果下一个元素值更大
                result[st.top()]=nums[j];//索引值和result容器相对应
                st.pop();
            }   
        st.push(j);//将元素下标入栈,这样可以随着栈弹出而递减
        }
        return result;
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值