栈与队列

栈先入后出,队列先入先出
image

  1. stack数据结构,push()/pop()都是void返回值,找元素需要用top()
  2. 递归本质上就是栈实现的,调用递归会把函数、参数等压入栈中,因此递归过深就会报segment fault

232.用栈实现队列

https://leetcode.cn/problems/implement-queue-using-stacks/description/
image

class MyQueue {
public:
    stack<int> stackIn;
    stack<int> stackOut;
    MyQueue() {

    }
    void push(int x) {
        stackIn.push(x);
    }
    int pop() {
        if(stackOut.empty()){//注意!!!!!!!
        while(!stackIn.empty())
        {
            stackOut.push(stackIn.top());
            stackIn.pop();
        }
        }
        int cur = stackOut.top();
        stackOut.pop();
        return cur;
    }
    int peek() {
        //类成员函数调用另一个成员函数用this->
        int cur = this->pop();
        stackOut.push(cur);
        return cur;
    }
    bool empty() {
        return stackIn.empty() && stackOut.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();
 */

225.用队列实现栈

https://leetcode.cn/problems/implement-stack-using-queues/description/
image

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

    }
    
    void push(int x) {
        q.push(x);
    }
    
    int pop() {
        int size = q.size();
        while(--size)
        {
            q.push(q.front());
            q.pop();
        }
        int cur = q.front();
        q.pop();
        return cur;
    }
    
    int top() {
        return q.back();
    }
    
    bool empty() {
        return q.empty();
    }
};

20.有效的括号

https://leetcode.cn/problems/valid-parentheses/submissions/493171286/
image

class Solution {
public:
    bool isValid(string s) {
        //先入后出,比如( ( ) ) 遇到第三个字符 先弹出第二个括号
        if("" == s) return true;
        if(s.size() % 2 != 0) return false;
        stack<char> st;
        for(int i = 0; i < s.size(); i++)
        {
            cout<<s[i]<<endl;
            if(s[i] == '(')
            st.push(')');

            else if(s[i] == '[')
            st.push(']');

            else if(s[i] == '{')
            st.push('}');
//这里是一定要用他妈的else if的 不然的话,对于() i = 0 入栈了 ) 会立即与 ( 作比较返回false!!!!!!!!!!!!!
            else if(st.empty()||st.top() != s[i]) return false;
            
            else
            st.pop();
        }
        return st.empty();
    }
};

1047.删除字符串中的所有重复项

https://leetcode.cn/problems/remove-all-adjacent-duplicates-in-string/description/
image

//更推荐用string,因为直接有push_back和pop_back()
class Solution {
public:
    string removeDuplicates(string s) {
        stack<char> st;
        for(int i = 0; i < s.size(); i++)
        {
            if(!st.empty() && st.top() == s[i])
            st.pop();

            else 
            st.push(s[i]); 
        }
        string res="";
        while(!st.empty())
        {
            res = st.top() + res;
            st.pop();
        }
        return res;
    }
};

150.逆波兰表达式求值

https://leetcode.cn/problems/evaluate-reverse-polish-notation/
image

class Solution {
public:
    int evalRPN(vector<string>& tokens) {
        stack<long long> st;
        for(int i = 0; i < tokens.size(); i++)
        {
            if(tokens[i]=="+" || tokens[i]=="-" || tokens[i]=="*" || tokens[i]=="/")
            {
                long long num1 = st.top(); //逆波兰表达式运算符至少在第三个
                st.pop();
                long long num2 = st.top();
                st.pop();

                if(tokens[i]=="+") st.push(num1 + num2); //这里需要注意计算顺序。比如10 5 / 先入后出,所以nums2 = 10
                if(tokens[i]=="-") st.push(num2 - num1);
                if(tokens[i]=="*") st.push(num2 * num1);
                if(tokens[i]=="/") st.push(num2 / num1);
            }
            else st.push(stoll(tokens[i]));
        }
        return st.top();
    }
};

239.滑动窗口求最大值

https://leetcode.cn/problems/sliding-window-maximum/description/
image

class Solution {
private:
    class Myque{
    public:
        deque<int> q;
        void push(int val){
            //队列中3 1 2 待入栈val = 5,需要把3 1 2全部出栈
            while(!q.empty() && val > q.back())
            q.pop_back();

            q.push_back(val);
        }
        
        void pop(int val){
            //比如刚刚那样,队列只有一个5了,就需要跳过两次出栈, 先进入的为front
            //一定注意是if!!!!!!!!!!!!!!
            if(!q.empty() && val == q.front())
            q.pop_front();
        }
        int max(){
            return q.front();
        }
    };
public:
    vector<int> maxSlidingWindow(vector<int>& nums, int k) {
        //关键就是没必要挨个push pop 就可以省去比较 比如1 3 -1 就不push1, 具体操作是push 1 -- push 3 (3>1)-- pop 1 -- push -1
        //保证push进来的比前面的都大时清空前面小的,前面的小就不动
        //这样可以保证队列里每次都是单调递减,不会出现5 2 3 因为push3就会pop2
        Myque que;
        vector<int> result;
        for(int i = 0; i < k; i++)
        {
            que.push(nums[i]);   
        }
        result.push_back(que.max());
        for(int i = k; i < nums.size(); i++)
        {
            que.pop(nums[i-k]);
            que.push(nums[i]);
            result.push_back(que.max());
        }
        return result;
    }
};

347.前K个高频元素

https://leetcode.cn/problems/top-k-frequent-elements/description/
image

class Solution {
public:
    class mycmp{
        //不要漏掉了public  operator后面的()  最后的分号!!!!!!!
        public:
        bool operator()(pair<int,int> &p1, pair<int,int> &p2){
            return p1.second>p2.second;
        }
    };
    vector<int> topKFrequent(vector<int>& nums, int k) {
        //得到一个nums数组每个元素和出现次数的map
        unordered_map<int,int> ump;
        for(int i = 0; i < nums.size(); i++)
        {
            ump[nums[i]]++;
        }
        //大小顶堆底层都是二叉树,都是从堆顶出栈,不同的是小顶堆顶是最小的,大顶堆顶是最大的,所以用小顶堆,依次把小的都弹出
        priority_queue<pair<int,int>, vector<pair<int,int>>, mycmp> pq;
        //这里因为要push map里的每个元素,所以要遍历
        for(auto it = ump.begin(); it != ump.end(); it++)
        {
            pq.push(*it);
            if(pq.size() > k){
                pq.pop();
            }
        }
        vector<int> res;
        for(int i = k - 1; i >= 0; i--)
        {
            res.push_back(pq.top().first);
            pq.pop();
        }
        return res;
    }
};
posted @ 2024-01-03 18:10  __Zed  阅读(20)  评论(0)    收藏  举报