首页 > 技术文章 > leetcode(c++)(单调栈)

fourmi 2022-05-04 13:55 原文

#include <iostream>
#include <stack>
#include <vector>
#include <queue>
#include <unordered_map>
#include <string>

using namespace std;

//最小栈
class MinStack
{
    public:
    stack<int>st;
    stack<int>minSt;
    void push(int x)
    {
        st.push(x);
        if(minSt.empty() || x <= minSt.top())
        {
            minSt.push(x);
        }
    }
    void pop()
    {
        int top = st.top();
        if(top == minSt.top())
        {
            minSt.pop();
        }
    }
    int top()
    {
        return st.top();
    }

    int getMin()
    {
        return minSt.top();
    }

};

//两个栈实现队列

class Myqueue{
    public: 
    stack<int>st;
    stack<int>queue;
    void push(int x)
    {
        st.push(x);
    }
    int top()
    {
        if(queue.empty())
        {
            while(!st.empty())
            {
                int val = st.top();
                st.pop();
                queue.push(val);
            }
        }
        return queue.top();
    }
    int pop()
    {
        top();
        int val = queue.top();
        return val;
    }
    bool empty()
    {
        return queue.empty() && st.empty();
    }
};

//两个队列实现一个栈
class MyStack{
    public:  
    queue<int>q1,q2;
    void push(int x)
    {
        if(q1.empty())q1.push(x);
        while(!q2.empty())
        {
            int val = q2.front();
            q2.pop();
            q1.push(val);
        }
        while(!q1.empty())
        {
            int val = q1.front();
            q1.pop();
            q2.push(val);
        }        
    }
    int pop()
    {
        int val = q2.front();
        q2.pop();
    }
    int front()
    {
        return q2.front();
    }
    bool empty()
    {
        return q1.empty() && q2.empty();
    }
};

class CircleQueue{
    public:
    vector<int>q;
    int front = 0, rear = -1, size = 0;
    CircleQueue(int k)
    {
        q = vector<int>(k);        
    }
    bool isFull()
    {
        return size == q.size();
    }
    bool isEmpty()
    {
        return size == 0;
    }
    int Front()
    {
        return isEmpty() ? -1 :q[front];
    }
    int Rear()
    {
        return isEmpty() ? -1 : q[rear];
    }

    bool enqueue(int x)
    {
        if(!isFull())
        {
            rear = (rear + 1) % q.size();
            q[rear] = x;
            ++size;
            return true;
        }
        else
        return false;
    }
    bool dequeu()
    {
        if(!isEmpty())
        {
            front = (front + 1) % q.size();
            --size;
            return true;
        }
        else
        {
            return false;
        }
    }
};


class MyDequeue{
    public:  
    int front = 0, rear = -1, size = 0,capacity = 0;
    vector<int>q;
    MyDequeue(int k)
    {
        q = vector<int>(k);
        capacity = k;
    }
    bool isFull()
    {
        return size == capacity;
    }
    bool isEmpty()
    {
        return size == 0;
    }
    int getFront()
    {
        return isEmpty() ? -1:q[front];
    }
    int getRear()
    {
        return isEmpty() ? -1:q[rear];
    }
    bool insertFirst(int x)
    {
        if(isFull())return false;
        if(--front < 0) front += capacity;
        q[front] = x;
        ++size;
        if(size == 1)rear = front;
        return true;
    }

    bool insertLast(int x)
    {
        if(isFull())return false;
        rear = (rear + 1) % capacity;
        q[rear] = x;
        ++size;
        return true;
    }

    bool deleteFirst()
    {
        if(isEmpty())return false;
        front  = (front + 1) % capacity;
        --size;
        return true;
    }

    bool deleteLast()
    {
        if(isEmpty())return false;
        if(--rear < 0)rear += capacity;
        --size;
        return true;
    }

};

void print(const vector<int>& res)
{
    for(int num : res)
    {
        cout << num << " ";
    }
    cout << endl;
}
//递增栈
vector<int>nextGreater(const vector<int>& nums)
{
    int n = nums.size();
    vector<int>res(n);
    stack<int>st;
    for(int i = n - 1; i >= 0; --i)
    {
        while(!st.empty() && nums[i] >= st.top())
        {
            st.pop();        
        }
        res[i] = st.empty() ? -1:st.top();
        st.push(nums[i]);
    }
    return res;
}

vector<int> nextGreaterElement(const vector<int>& nums1, const vector<int>& nums2)
{
    unordered_map<int,int>map;
    stack<int>st;
    int n = nums2.size();
    for(int i = n - 1; i >= 0; --i)
    {
        while(!st.empty() && nums2[i] >= st.top())
        {
            st.pop();
        }
        map[nums2[i]] = st.empty() ? -1:st.top();
        st.push(nums2[i]);
    }
    n = nums1.size();
    vector<int>res;
    for(int i = 0 ; i < n; ++i)
    {
        if(map.find(nums1[i]) != map.end())
        {
            res.emplace_back(map[nums1[i]]);
        }
        else
        {
            res.emplace_back(-1);
        }
    }
    return res;
}

vector<int>nextGreaterElement(const vector<int>& input)
{
    int n = input.size();
    vector<int>res(n);
    stack<int>st;
    for(int i = 2 * n - 1; i >= 0; --i)
    {
        while(!st.empty() && input[i % n] >= st.top())
        {
            st.pop();
        }
        res[i % n] = st.empty() ? -1 : st.top();
        st.push(input[i % n]);
    }
    return res;
}

vector<int>dailyTemperatures(const vector<int>& tmp)
{
    int n = tmp.size();
    vector<int>res(n);
    stack<int>st;
    for(int i = n - 1; i >= 0; --i)
    {
        while(!st.empty() && tmp[i] >= tmp[st.top()])st.pop();
        res[i] = st.empty() ? 0 : st.top() - i;
        st.push(i);
    }
    return res;
}

string removeDuplicateLetters(string s) {
    
    vector<int> vis(26), num(26);
    for(char c:s)
    {
        ++num[c-'a'];
    }

    string res;
    for(char c:s)
    {
        if(!vis[c - 'a'])
        {
            while(!res.empty() && res.back() > c)
            {
                if(num[res.back() - 'a'] > 0)
                {
                    vis[res.back() -'a'] = 0;
                    res.pop_back();
                }
                else
                {
                    break;
                }
            }
            vis[c - 'a'] = 1;
            res.push_back(c);            
        }
       --num[c - 'a'];
    }  
     return res;
}  

string removeKdigits(string s,int k)
{
    stack<char>st;
    for(char c:s)
    {
        while(!st.empty() && c < st.top() && k > 0)
        {
            st.pop();
            --k;
        }
        st.push(c);
    }
    while(k-- > 0)st.pop();
    bool zero = false;
    string res = "";
    while(!st.empty())
    {
        char c = st.top();
        st.pop();   
        res.push_back(c);             
    }
    reverse(res.begin(),res.end());
    res = to_string(stoi(res));
    return res;
    
}

int trap(const vector<int>& height)
{
    int res = 0;
    int n = height.size();
    vector<int>left(n),right(n);
    left[0] = height[0];
    right[n-1] = height[n-1];
    for(int i = 1; i < n; ++i)
    {
        left[i] = max(height[i],left[i-1]);        
    }
    for(int i = n - 2; i >= 0; --i)
    {
        right[i] = max(height[i],right[i+1]);
    }
    for(int i = 0; i < n; ++i)
    {
        res += min(left[i],right[i]) - height[i];
    }
    return res;
}

int trapI(const vector<int>& nums)
{
    stack<int>st;
    int res = 0, n = nums.size();
    for(int i = 0; i < n ;++i)
    {
        while(!st.empty() && nums[i] > nums[st.top()])
        {
            int pre = st.top();
            st.pop();
            if(st.empty())break;
            int minHeight = min(nums[i],nums[st.top()]);
            res += (minHeight - nums[pre]) * ( i - st.top() - 1);
        }
        st.push(i);
    }
    return res;
}

int largestRectangleArea(const vector<int>& nums)
{
    stack<int>st;
    int n = nums.size();
    int res = 0;
    for(int i = 0; i < n; ++i)
    {
        while(!st.empty() && nums[i] <= nums[st.top()])
        {
            int pre = st.top();
            st.pop();
            int preHeight = nums[pre];
            int width = i - (st.empty() ? 0 :st.top() + 1);
            res = max(res, preHeight * width);
        }
        st.push(i);
    }
    while(!st.empty())
    {
        int preHieght = nums[st.top()];
        st.pop();
        int width = n - (st.empty() ? 0 : st.top() + 1);
        res = max(res,preHieght * width);
    }
    return res;
}

int main()
{
    vector<int>nums{2,1,2,4,3};
    print(nextGreater(nums));

    //LeetCode496
    vector<int>nums1 = {4,1,2};
    vector<int>nums2 = {1,3,4,2};
    print(nextGreaterElement(nums1,nums2));

    //LeetCode503
    vector<int>input{1,2,1};
    print(nextGreaterElement(input));
    
    //LeetCode739
    vector<int>tmp{73,74,75,71,69,72,76,73};
    print(dailyTemperatures(tmp));

    //LeetCode316
    string s = "bcabc";
    cout << removeDuplicateLetters(s) << endl;

    //LeetCode402
    s = "10200";    
    int k = 1;

    // s = "1433219";
    // k = 3;
    cout << removeKdigits(s,k) << endl;

    //LeetCode42
    vector<int>height{4,2,0,3,2,5};
    cout << trap(height) << endl;
    cout << trapI(height) << endl;

    //LeetCode84

    height = {2,1,5,6,2,3};
    cout << largestRectangleArea(height) << endl;
    return 0;
}

 

推荐阅读