算法 day3

今天覆習單調棧

單調棧:尋找最左邊第一個比自己(嚴格)小/大的數

單調隊列:查找滑動窗口中的最值

基本上求滑動窗口的最值就是使用單調隊列

【leetcode】min stack

使用兩個棧,其中一個保存最小值。

class MinStack {
public:
    /** initialize your data structure here. */
    stack<int> minstack,sstack;
    MinStack() {
        
    }
    
    void push(int x) {
        if(minstack.empty())
        {
            minstack.push(x);
            sstack.push(x);
        }
        else
        {
            minstack.push(min(minstack.top(),x));
            sstack.push(x);
        }
    }
    
    void pop() {
        minstack.pop(); 
        sstack.pop();
    }
    
    int top() {
        return sstack.top();
    }
    
    int getMin() {
        return minstack.top();
    }
};

/**
 * Your MinStack object will be instantiated and called as such:
 * MinStack* obj = new MinStack();
 * obj->push(x);
 * obj->pop();
 * int param_3 = obj->top();
 * int param_4 = obj->getMin();
 */

【leetcode】柱形圖中的面積最大的矩形

單調棧

class Solution {
public:
    int trap(vector<int>& height) {
        int a[6] = {2,1,5,6,2,3};
        stack<int> ss;
        for(int i=0;i<6;i++)
        {
            if(ss.empty()||ss.top()<a[i])
            {
                ss.push(a[i]);
            }
            else
            {
                while(!ss.empty()&&ss.top()>a[i])
                {
                    ss.pop();
                }
                ss.push(a[i]);
            }
        }

        while(!ss.empty())
        {
            printf("%d ",ss.top());
            ss.pop();
        }
        return 0;
    }
};

單調棧寫的有點問題的

class Solution {
public:
    int largestRectangleArea(vector<int>& heights) {
        int n = heights.size();
        vector<int> left (n,-1);
        vector<int> right(n,n);
        stack<int> ss;
        for(int i = 0;i<n;i++)
        {
            while(!ss.empty() && heights[ss.top()]>heights[i])
            {
                right[ss.top()] = i;
                ss.pop();
            }
            
            if(!ss.empty())
            { 
                left[i] = ss.top();
            }
            ss.push(i);
            
        }
        int maxs = 0;
        for(int i=0;i<n;i++)
        {
            printf("left:%d i:%d right:%d\n",left[i],i,right[i]);
            int tmps = 0;
            tmps = heights[i]*(right[i]-left[i]-1);
            if(tmps>maxs)
            maxs = tmps;
        }          
        return maxs;
    }
};

 

【leetcode】下一個更大元素1

class Solution {
public:
    vector<int> nextGreaterElement(vector<int>& nums1, vector<int>& nums2) {
        map<int,int> mmap;
        stack<int> ss;
        vector<int> res;
        //構造一個單調遞減棧
        for(int i=0;i<nums2.size();i++)
        {
            if(ss.empty()||ss.top()>nums2[i])
            {
                ss.push(nums2[i]);
            }
            else
            {
                while(!ss.empty()&&ss.top()<nums2[i])
                {
                    mmap[ss.top()] = nums2[i];
                    ss.pop();
                }
                ss.push(nums2[i]);
            }
        }

        while(!ss.empty())
        {
            mmap[ss.top()] = -1;
            ss.pop();
        }

        for(int i=0;i<nums1.size();i++)
        {
            res.push_back(mmap[nums1[i]]);
        }
        return res;

    }
};

【leetcode】下一個更大的元素2

class Solution {
public:
    vector<int> nextGreaterElements(vector<int>& nums) {
        stack<int> ss;
        vector<int > res(nums.size(),-1);
        for(int j=0;j<nums.size()*2;j++)
        {
            int i = j%nums.size();
            if(ss.empty() || nums[ss.top()]>nums[i])
            {                    
                ss.push(i);
            }
            else 
            {
                while(!ss.empty() && nums[ss.top()]<nums[i])
                {
                    res[ss.top()] = nums[i];
                    ss.pop();
                }
                ss.push(i);
            }

        }
        return res;
    }
};

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章