棧和佇列

木木ちゃん發表於2024-11-08

棧和佇列

  1. 232.用棧實現佇列

雙棧的想法。需要在出棧時轉移棧中元素到另一個棧,入棧時轉移棧中元素到初始的棧。

class MyQueue {
public:
    stack<int> instack,outstack;

    MyQueue() {
    }
    
    void push(int x) {
        while(!outstack.empty())
        {
            int element = outstack.top();
            outstack.pop();
            instack.push(element);
        }
        instack.push(x);
    }
    
    int pop() {
        while(!instack.empty())
        {
            int element = instack.top();
            instack.pop();
            outstack.push(element);
        }
        int ans = outstack.top();
        outstack.pop();
        return ans;
    }
    
    int peek() {
        while(!instack.empty())
        {
            int element = instack.top();
            instack.pop();
            outstack.push(element);
        }
        int ans = outstack.top();
        return ans;
    }
    
    bool empty() {
        return instack.empty() && outstack.empty();
    }
};

/**
 * Your MyQueue object will be instantiated and called as such:
 * MyQueue* obj = new MyQueue();
 * obj->push(x);
 * int param_2 = obj->pop();
 * int param_3 = obj->peek();
 * bool param_4 = obj->empty();
 */
  1. 225.用佇列實現棧

同雙棧法。

class MyStack {
public:
    queue<int> a;
    queue<int> b;
    MyStack() {

    }
    
    void push(int x) {
        a.push(x);
    }
    
    int pop() {
        while(a.size()>1)
        {
            b.push(a.front());
            a.pop();
        }
        int ans=a.back();
        a.pop();
        while(!b.empty())
        {
            a.push(b.front());
            b.pop();
        }
        return ans;
    }
    
    int top() {
        int ans=a.back();
        while(!a.empty())
        {
            b.push(a.front());
            a.pop();
        }
        while(!b.empty())
        {
            a.push(b.front());
            b.pop();
        }
        return ans;
    }
    
    bool empty() {
        return a.empty();
    }
};

/**
 * Your MyStack object will be instantiated and called as such:
 * MyStack* obj = new MyStack();
 * obj->push(x);
 * int param_2 = obj->pop();
 * int param_3 = obj->top();
 * bool param_4 = obj->empty();
 */
  1. 1441.用棧操作構建陣列

一個個對比需要的數字就行。

class Solution {
public:
    vector<string> buildArray(vector<int>& target, int n) {
        int counter = 0;
        vector<string> operations;
        for (int i = 1; i <= n; i++)
        {
            // Match the elements;
            if(counter >= target.size()) break;
            operations.emplace_back("Push");
            if (i == target[counter])
            {
                counter ++;
                continue;
            }
            else
            {
                operations.emplace_back("Pop");
            }
        }
        return operations;
    }
};

單調棧

棧內部單調遞增或單調遞減的棧。可以用來記錄一些關於可覆蓋面積,最近的符合某些條件的下標資訊等等。
例如我們有:
[6,7,5,2,4,5,9,3]
從左到右尋找左邊第一個比自己小的元素,則可以使用單調棧。
所以:
[-1,0,-1,-1,3,4,5,3]
從右向左尋找右邊第一個比自己小的元素,則有:
[2,2,3,8,7,7,7,8]
例如:我們有這樣一道題
84. 柱狀圖中最大的矩形
這時候我們可以利用單調棧來尋找一根柱子能夠覆蓋的最大範圍。
從左向右遍歷,當新的元素小於等於棧頂元素時不斷出棧,直到棧空或棧頂元素小於當前元素為止。將索引入棧。

class Solution {
public:
    int largestRectangleArea(vector<int>& heights) {
        int n = heights.size();
        vector<int> left(n), right(n); // Initialize the vector;

        stack<int> mono_stack;
        for (int i=0;i<n;i++)
        {
            // non-empty and the top of the mono-stack is bigger than heights:
            while(!mono_stack.empty() && heights[mono_stack.top()] >= heights[i])
            {
                mono_stack.pop();
            }
            // When the top is smaller or none in mono_stack, put the values.
            left[i] = (mono_stack.empty() ? -1 : mono_stack.top());
            mono_stack.push(i);
        }
        
        mono_stack = stack<int>();
        for (int i=n-1;i > -1 ;i--)
        {
            // non-empty and the top of the mono-stack is bigger than heights:
            while(!mono_stack.empty() && heights[mono_stack.top()] >= heights[i])
            {
                mono_stack.pop();
            }
            // When the top is smaller or none in mono_stack, put the values.
            right[i] = (mono_stack.empty() ? n : mono_stack.top());
            mono_stack.push(i);
        }
        int ans = 0;
        for (int i = 0; i < n; i++)
        {
            ans = max(ans, heights[i] * (right[i]-left[i]-1));
        }
        return ans;
    }
};
  1. 84. 柱狀圖中最大的矩形

題解一:單調棧

class Solution {
public:
    int largestRectangleArea(vector<int>& heights) {
        int n = heights.size();
        vector<int> left(n), right(n); // Initialize the vector;

        stack<int> mono_stack;
        for (int i=0;i<n;i++)
        {
            // non-empty and the top of the mono-stack is bigger than heights:
            while(!mono_stack.empty() && heights[mono_stack.top()] >= heights[i])
            {
                mono_stack.pop();
            }
            // When the top is smaller or none in mono_stack, put the values.
            left[i] = (mono_stack.empty() ? -1 : mono_stack.top());
            mono_stack.push(i);
        }
        
        mono_stack = stack<int>();
        for (int i=n-1;i > -1 ;i--)
        {
            // non-empty and the top of the mono-stack is bigger than heights:
            while(!mono_stack.empty() && heights[mono_stack.top()] >= heights[i])
            {
                mono_stack.pop();
            }
            // When the top is smaller or none in mono_stack, put the values.
            right[i] = (mono_stack.empty() ? n : mono_stack.top());
            mono_stack.push(i);
        }
        int ans = 0;
        for (int i = 0; i < n; i++)
        {
            ans = max(ans, heights[i] * (right[i]-left[i]-1));
        }
        return ans;
    }
};

最佳化

class Solution {
public:
    int largestRectangleArea(vector<int>& heights) {
        int n = heights.size(),ans=0;
        stack<int> mono_stack;
        mono_stack.push(-1);
        for (int i=0;i<n;i++)
        {
            while(mono_stack.top()!=-1 && heights[i] < heights[mono_stack.top()])
            {
                int cur_height = heights[mono_stack.top()];
                mono_stack.pop();
                ans = max(ans, cur_height*(i - mono_stack.top() - 1));
            }
            mono_stack.push(i);
        }

        while(mono_stack.top()!=-1)
        {
            int cur_height = heights[mono_stack.top()];
            mono_stack.pop();
            ans = max(ans, cur_height*((n - 1) - mono_stack.top()));
        }
        return ans;
    }
};

未完待續

相關文章