zoukankan      html  css  js  c++  java
  • 单调栈

      从栈低到栈顶元素依次减小的单调栈

    /*
     *单调栈:从栈低到栈顶元素依次减小,栈低元素最大 
     *解决问题:求左边离他最近比它大的数,右边离他最近比它大的数 
     */
    #include <iostream>
    #include <stack>
    #include <vector>
    using namespace std;
    
    int main()
    {
        vector<int> arr{3,5,4,1,6,8};
        stack<int> stack;
        for(int i=0;i<arr.size();++i)
        {
            //因为谁出栈,谁就是离它右边最近比他大的,它的下一个元素是左边离它最近比他大的 
            while(!stack.empty()&&arr.at(stack.top())<=arr.at(i))
            {
                cout<<arr.at(stack.top())<<": right_max="<<arr.at(i)<<"	";
                stack.pop();
                if(!stack.empty())
                    cout<<" left_max="<<arr.at(stack.top())<<endl;
                else
                    cout<<" left_max=nullptr"<<endl;
            }
            stack.push(i);
        }
        while(!stack.empty())
        {
            cout<<arr.at(stack.top())<<": right_max=nullptr"<<"	";
            stack.pop();
            if(!stack.empty())
                cout<<" left_max="<<arr.at(stack.top())<<endl;
            else
                cout<<" left_max=nullptr"<<endl;
        }
        return 0;    
    } 

      从栈低到栈顶元素依次增大的单调栈

    /*
     *单调栈:从低到顶依次增大,栈低元素最小
     *解决问题:左边和右边离他最近比他小的元素 
     */
    #include <iostream>
    #include <vector>
    #include <stack>
    using namespace std;
    
    int main()
    {
        vector<int> arr{3,5,4,1,6,8};
        stack<int> stack;
        for(int i=0;i<arr.size();++i)
        {
            //因为谁出栈,谁就是离它右边最近比他小的,它的下一个元素是左边离它最近比他小的 
            while(!stack.empty()&&arr.at(stack.top())>=arr.at(i))
            {
                cout<<arr.at(stack.top())<<": right_min="<<arr.at(i)<<"	";
                stack.pop();
                if(!stack.empty())
                    cout<<" left_min="<<arr.at(stack.top())<<endl;
                else
                    cout<<" left_min=nullptr"<<endl;
            }
            stack.push(i);
        }
        while(!stack.empty())
        {
            cout<<arr.at(stack.top())<<": right_min=nullptr"<<"	";
            stack.pop();
            if(!stack.empty())
                cout<<" left_min="<<arr.at(stack.top())<<endl;
            else
                cout<<" left_min=nullptr"<<endl;
        }
        return 0;
    }

      应用

    /*
     *单调栈实例:最大子矩阵的大小
     *1 0 1 1
     *1 0 1 1
     *1 0 1 1
     */
    #include <iostream>
    #include <vector>
    #include <stack>
    using namespace std;
    
    class MaxSubMatrix
    {
        public:
            int max_sub_matrix(const vector<vector<int> > &m);
        private:
            int max_sub_matrix_core(const vector<int> &m);
    };
    int MaxSubMatrix::max_sub_matrix(const vector<vector<int> > &m)
    {
        if(m.empty()||m.size()<=0||m.at(0).size()<=0)
            return -1;
            
        int maxArea=0;
        vector<int> m1(m.at(0).size(),0);
        for(int i=0;i<m.size();++i)
        {
            for(int j=0;j<m.at(0).size();++j)
                m1.at(j)=m.at(i).at(j)==0?0:m1.at(j)+1;
            maxArea=max(maxArea,max_sub_matrix_core(m1));
        }
        return maxArea;
    }
    int MaxSubMatrix::max_sub_matrix_core(const vector<int> &m)
    {
        if(m.empty()||m.size()<=0)
            return -1;
        
        //栈中的元素可以递增,遇到小的元素就结算当前栈中的面积 
        stack<int> stack;
        int maxArea=0;
        for(int i=0;i<m.size();++i)
        {
            //遇到比栈顶小的元素就结算面积 
            while(!stack.empty()&&m.at(i)<=m.at(stack.top()))
            {
                int h=stack.top();
                stack.pop();
                int left=stack.empty()?-1:stack.top();
                maxArea=max(maxArea,(i-left-1)*m.at(h));
            }
            stack.push(i);
        }
        
        while(!stack.empty())
        {
            int h=stack.top();
            stack.pop();
            int left=stack.empty()?-1:stack.top();
            int right=m.size();
            maxArea=max(maxArea,(right-left-1)*m.at(h));
        }
        return maxArea;
    }
    int main()
    {
        vector<vector<int> > v{{0,0,0,1,0},{1,0,1,1,1},{1,0,1,1,1},{1,1,1,1,1}};
        MaxSubMatrix ms;
        cout<<ms.max_sub_matrix(v)<<endl;
        return 0;
    }
  • 相关阅读:
    Linux服务器查看日志命令总结
    nginx高可用(5)
    nginx动静分离(4)
    nginx负载均衡(3)
    nginx反向代理(2)
    nginx安装及使用(1)
    Nginx 简易教程
    uiautomator2中文文档
    TKinter之输入框
    nginx解决反向代理session丢失问题
  • 原文地址:https://www.cnblogs.com/tianzeng/p/10544837.html
Copyright © 2011-2022 走看看