Monotone stack 5 questions

1. Leetcode739. Daily temperature

insert image description here
Monotonic stack O(n)
stack storage subscript
When the next value is less than or equal to the previous value, it is stored in the stack until the current value is greater than the previous value, and all the ones less than the previous value are popped, then the maximum value on the right side of the popped value is of course the current value value


class Solution {
    
    
public:
    vector<int> dailyTemperatures(vector<int>& temperatures) {
    
    
       stack<int>st;
       vector<int>ans(temperatures.size(),0);
       for(int i=0;i<temperatures.size();i++){
    
    
           while(!st.empty()&&temperatures[i]>temperatures[st.top()]){
    
    
                ans[st.top()]=i-st.top();
                st.pop();
           }
           st.push(i);
       }
       return ans;
    }
};

2. Leetcode496. Next Greater Element I

insert image description here
Why use a monotonic stack for num2 here, but num1 can still find the next maximum value, mainly because num2 includes num1, and the two arrays are not repeated, then you can find the subscript of num1 through value mapping

class Solution {
    
    
public:
    vector<int> nextGreaterElement(vector<int>& nums1, vector<int>& nums2) {
    
    
          vector<int>ans(nums1.size(),-1);
          unordered_map<int,int>umap;
          stack<int>st;

          for(int i=0;i<nums1.size();i++){
    
    
              umap[nums1[i]]=i;
          }
          for(int i=0;i<nums2.size();i++){
    
    
              while(!st.empty()&&nums2[i]>nums2[st.top()]){
    
    
                //这里注意nums2值的范围>nums1,可能不能在umap中查到
                if(umap.count(nums2[st.top()])>0){
    
    
                    ans[umap[nums2[st.top()]]]=nums2[i];    
                }
                st.pop();
              }
              st.push(i);
          }
          return ans;

    }
};

3. LeetCode503. The Next Bigger Element II

insert image description here
The surface is that the loop is actually twice as large, and it is enough to ensure that the number in the back is followed by the number in front of it.

class Solution {
    
    
public:
    vector<int> nextGreaterElements(vector<int>& nums) {
    
    
         int len=nums.size();
         vector<int>ans(len,-1);
         vector<int>nums1(nums.begin(),nums.end());
         nums.insert(nums.end(),nums1.begin(),nums1.end());
         stack<int>st;

         for(int i=0;i<len*2-1;i++){
    
    
             while(!st.empty()&&nums[i]>nums[st.top()]){
    
    
                 if(st.top()<len)ans[st.top()]=nums[i];
                 st.pop();
             }
             st.push(i);
         }
         return ans;

    }
};

4. Leetcode42. Catch the rain

insert image description here

Method 1: Double pointer method
Time complexity O(N 2 ) Timeout
Find the maximum value on both sides
Sweep

class Solution {
    
    
public:
    int trap(vector<int>& height) {
    
     
       int ans=0;
       for(int i=1;i<height.size()-1;i++){
    
    
           int maxl=0,maxr=0;
           for(int l=i-1;l>=0;l--){
    
    
               maxl=max(maxl,height[l]);
           }
           for(int r=i+1;r<height.size();r++){
    
    
               maxr=max(maxr,height[r]);
           }
           int h=min(maxr,maxl);
           if(h>height[i])ans+=h-height[i];
           
       }
       return ans;
    }
};

Method 2: Dynamic programming solution
access the maximum value on both sides
Sweep

class Solution {
    
    
public:
    int trap(vector<int>& height) {
    
    
       vector<int>l(height.size(),0);
       vector<int>r(height.size(),0);
       int ans=0;
       l[0]=height[0];
       r[height.size()-1]=height[height.size()-1];

       for(int i=1;i<height.size();i++){
    
    
           l[i]=max(l[i-1],height[i]);
       }
       for(int i=height.size()-2;i>=0;i--){
    
    
           r[i]=max(r[i+1],height[i]);
       }
       for(int i=1;i<height.size()-1;i++){
    
    
           int h=min(l[i-1],r[i+1]);
           if(h>height[i])ans+=h-height[i];
       }
       return ans;
    }
};

Method 3: Monotone stack method:

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

      
    }
};

5. Leetcode84. The largest rectangle in the bar chart

When the column covers the i-th rectangle, if the two sides are greater than or equal to this rectangle, it can be widened to both sides,
and if it is smaller than the rectangle, it cannot be
insert image description here

Method 1: Double pointer
Find the first value lower than i on both sides of i, rl is the width, height is height[i], the
time complexity is O(n 2 ) If it times out, it will not be written.

Method 2: Dynamic Programming

class Solution {
    
    
public:
    int largestRectangleArea(vector<int>& heights) {
    
    
        //记录每一个每一个柱子左边,右边第一个小于该柱子的下标
        vector<int>l(heights.size(),0);
        vector<int>r(heights.size(),0);
        l[0]=-1;
        int ans=0;
        for(int i=1;i<heights.size();i++){
    
    
            int t=i-1;
            while(t>=0&&heights[t]>=heights[i])t=l[t];
            l[i]=t;
        }
        r[heights.size()-1]=heights.size();
        for(int i=heights.size()-2;i>=0;i--){
    
    
            int t=i+1;
            while(t<heights.size()&&heights[t]>=heights[i])t=r[t];
            r[i]=t;
        }
        for(int i=0;i<heights.size();i++){
    
    
            int w=r[i]-l[i]-1;
            if(w>0)ans=max(heights[i]*w,ans);
        }
        return ans;
    }
};

Method 3: Monotonic Stack

class Solution {
    
    
public:
    int largestRectangleArea(vector<int>& heights) {
    
    
        int ans=0;
        stack<int>st;
        //最边缘的两个需要算在内所以加入两个更小的,同时可以防止访问空栈
        heights.insert(heights.begin(), 0); // 数组头部加入元素0
        heights.push_back(0); // 数组尾部加入元素0
      
        for(int i=0;i<heights.size();i++){
    
    
            while(!st.empty()&&heights[i]<heights[st.top()]){
    
    
                int mid=st.top();
                st.pop(); 
                int w=i-st.top()-1;
                ans=max(ans,w*heights[mid]);        
            }
            st.push(i);
        }
        return ans;

    }
};

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=324117663&siteId=291194637