• 代码随想录算法训练营刷题复习4 :单调栈


    单调栈

    单调栈
    如果题目出现典型的
    【左小 中大(栈中左侧元素都比此值小) || 右小】(寻找右侧第一个比此值小的元素)
    【左大 中小(栈中左侧元素都比此值大) || 右大】(寻找右侧第一个比此值大的元素)
    数据关系的话,可以考虑使用单调栈解决问题

    1. 739. 每日温度

    2. 496. 下一个更大元素 I

    3. 503. 下一个更大元素 II

    4. 42. 接雨水

    5. 84. 柱状图中最大的矩形这个题忽略了对数组头和尾添加0以方便对头和尾元素的处理

    4、5这两个题可以总结为单调栈中求面积问题:找所求区域的高和宽

    739. 每日温度

    class Solution {
    public:
        vector<int> dailyTemperatures(vector<int>& temperatures) {
            if(temperatures.size()<=1)
                return vector<int>(0);
            //需要用到栈和数组
            stack<int> st;
            vector<int> result(temperatures.size(),0);
            // 初始化把第一个元素的下标入栈
            st.push(0);
            for(int i=1;i<temperatures.size();i++) {
                //栈顶的元素值与当前遍历的值作比较
                if(temperatures[i] <= temperatures[st.top()]) {
                    st.push(i);
                }
                else {
                    //遇到第一个比当前值大的值时,用while循环来循环处理
                    while(!st.empty() && temperatures[i] > temperatures[st.top()])
                    {
                        result[st.top()] = i-st.top();
                        st.pop();
                    }
                    //处理结束说明栈中已经没有比当前遍历元素还小的值了,就把i入栈
                    st.push(i);
                }
            }
            return result;
            
        }
    };
    

    496. 下一个更大元素 I

    class Solution {
    public:
        vector<int> nextGreaterElement(vector<int>& nums1, vector<int>& nums2) {
            unordered_map<int,int> umap;
            //想要存 <键值,下标>这个关系
            // 下文中需要判断nums2中的值是否在nums1中出现,下标零出现误判,故使用i+1
            for(int i=0;i<nums1.size();i++) {
                umap[nums1[i]]=i+1;
            }
    
            if(nums1.size()==0 || nums2.size()==0)
                return vector<int>(nums1.size(),-1);
            
            stack<int> st;
            vector<int> ans(nums1.size(),-1);
            //这个数据没必要存了其实
            // vector temp(nums2.size(),-1);
            st.push(0);
            for(int i=1;i<nums2.size();i++) {
                if(nums2[i] <= nums2[st.top()]) {
                    st.push(i);
                }
                else {
                    while(!st.empty() && nums2[i] > nums2[st.top()]) {
                        // temp[st.top()] = nums2[i];
                        if(umap[nums2[st.top()]]!=0) {
                            ans[umap[nums2[st.top()]] -1] = nums2[i];
                        }
                        st.pop();
                    }
                    st.push(i);
                }
            }
            return ans;
        }
    };
    

    503. 下一个更大元素 II

    class Solution {
    public:
        vector<int> nextGreaterElements(vector<int>& nums) {
            //通过复制数组,将循环问题转化为不循环问题
            vector<int> nums1(nums.begin(),nums.end());
            // insert函数参数需要,插入位置,以及插入的元素范围
            nums.insert(nums.end(),nums1.begin(),nums1.end());
    
            stack<int> st;
            vector<int> res(nums.size(),-1);
            st.push(0);
            for(int i=1;i<nums.size();i++) {
                if(nums[i]<=nums[st.top()]) {
                    st.push(i);
                }
                else {
                    while(!st.empty() && nums[i]>nums[st.top()] ) {
                        res[st.top()] = nums[i];
                        st.pop();
                    }
                    st.push(i);
                }
            }
            //恢复原先数组大小
            res.resize(nums.size()/2);
            return res;
        }
    };
    

    42. 接雨水

    class Solution {
    public:
        int trap(vector<int>& height) {
            if(height.size()<=2)
                return 0;
            stack<int> st;
            // vector res(height.size(),0);
            st.push(0);
            int result = 0;
            for(int i=1;i<height.size();i++) {
                if(height[i] < height[st.top()]) {
                    st.push(i);
                }
                else if(height[i] == height[st.top()]) {
                    st.pop();
                    st.push(i);
                }
                else {
                    while(!st.empty() && height[i] > height[st.top()]) {
                        int mid = st.top();
                        st.pop();
                        if(!st.empty()){
                            int left = st.top();
                            int w = i-left-1;
                            int h = min(height[i],height[st.top()])-height[mid];
                            result+=h*w;
                        }
                    }
                    st.push(i);
                }
            }
            return result;
        }
    };
    

    84. 柱状图中最大的矩形

    class Solution {
    public:
        int largestRectangleArea(vector<int>& heights) {
            if(heights.size()==0)
                return 0;
            if(heights.size()==1)
                return heights[0];
            
            //这里对原始数组的头尾添加0值忘记考虑了
            heights.insert(heights.begin(),0);
            heights.push_back(0);
            
            stack<int> st;
            int res=0;
            st.push(0);
            for(int i=1;i<heights.size();i++) {
                if(heights[i]>heights[st.top()])
                    st.push(i);
                else if(heights[i] == heights[st.top()]) {
                    st.pop();
                    st.push(i);
                }
                else {
                    while(!st.empty() && heights[i]< heights[st.top()]) {
                        int mid = st.top();
                        st.pop();
                        if(!st.empty()) {
                            int left = st.top();
                            int w = i-left-1;
                            res = max(res,w*heights[mid]);
                        }
                    }
                    st.push(i);
                }
            }
            return res;
        }
    };
    
  • 相关阅读:
    一篇全面而且透彻的RabbitMQ性能优化指南
    圆角属性border-radius: 50%;与不透明度opacity和rgba(opacity:0.5---半透明)
    技术分享 | Selenium多浏览器处理
    环境多介质逸度模型与典型案例【代码】应用
    HTB靶场 Perfection
    配置nodejs的俩小脚本
    寻找可靠的软件外包开发公司
    【Python】python使用docxtpl生成word模板
    基于java的高速公路收费系统 计算机毕业设计
    2023,简历石沉大海?软件测试岗位真的已经饱和了....
  • 原文地址:https://blog.csdn.net/cir_sky/article/details/139753806