3. leetcode(栈和队列 )

1. leetcode 232 用栈实现队列

class MyQueue {
    
    
public:
    stack<int> stIn;
    stack<int> stOut;
    MyQueue() {
    
    

    }
    // 入栈无返回,有参数
    void push(int x) {
    
    
        stIn.push(x);
    }
    // 出栈有返回,返回出栈的元素
    int pop() {
    
    
        //只有当stOut为空时,再从stIn中导入全部数
        if (stOut.empty()) {
    
    
            //倒入数据,直到stIn为空
            while(!stIn.empty()) {
    
    
                stOut.push(stIn.top());
                stIn.pop();
            }
        }
        //出栈的有元素,可以出栈,临时保存栈顶
        int front = stOut.top();
        stOut.pop();
        return front;
    }
    
    int peek() {
    
    
        int res = this->pop();  //直接使用已有的pop函数
        stOut.push(res); // 因为pop函数弹出了元素res,所以添加回去
        return res;
    }
    
    bool empty() {
    
    
        return stOut.empty() && stIn.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();
 */

2. leetcode 225 用队列实现栈

//两个队列
class MyStack {
    
    
public:
    queue<int> queue1;
    queue<int> queue2;

    /** Initialize your data structure here. */
    MyStack() {
    
    

    }

    /** Push element x onto stack. */
    void push(int x) {
    
    
        queue2.push(x);
        while (!queue1.empty()) {
    
    
            queue2.push(queue1.front());
            queue1.pop();
        }
        swap(queue1, queue2);
    }
    
    /** Removes the element on top of the stack and returns that element. */
    int pop() {
    
    
        int r = queue1.front();
        queue1.pop();
        return r;
    }
    
    /** Get the top element. */
    int top() {
    
    
        int r = queue1.front();
        return r;
    }
    
    /** Returns whether the stack is empty. */
    bool empty() {
    
    
        return queue1.empty();
    }
};


// 一个队列
// 一个队列在模拟栈弹出元素的时候只要将队列头部的元素(除了最后一个元素外)
// 重新添加到队列尾部,此时弹出的元素就是栈的顺序


class MyStack {
    
    
public:
    queue<int> q;

    /** Initialize your data structure here. */
    MyStack() {
    
    

    }

    /** Push element x onto stack. */
    void push(int x) {
    
    
        int n = q.size();
        q.push(x);
        for (int i = 0; i < n; i++) {
    
    
            q.push(q.front());
            q.pop();
        }
    }
    
    /** Removes the element on top of the stack and returns that element. */
    int pop() {
    
    
        int r = q.front();
        q.pop();
        return r;
    }
    
    /** Get the top element. */
    int top() {
    
    
        int r = q.front();
        return r;
    }
    
    /** Returns whether the stack is empty. */
    bool empty() {
    
    
        return q.empty();
    }
};


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

    }
    
    void push(int x) {
    
    
        que.push(x);
    }
    
    int pop() {
    
    
        int size = que.size();
        size--;
        while (size--) {
    
    
            que.push(que.front());
            que.pop();
        }
        int res = que.front();
        que.pop();
        return res;
    }
    
    int top() {
    
    
        return que.back();
    }
    
    bool empty() {
    
    
        return que.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();
 */

3. leetcode 20 有效的括号

class Solution {
    
    
public:
    bool isValid(string s) {
    
    
        stack<int> st;
        for (int i = 0; i < s.size(); i++) {
    
    
            if (s[i] == '(') {
    
    
                st.push(')');
            } else if (s[i] == '{') {
    
    
                st.push('}');
            } else if (s[i] == '[') {
    
    
                st.push(']');
    //第三种情况 遍历字符串匹配过程中,栈已经为空,没有匹配的字符了,说明有括号没有找到对应的左括号 return false
    //第二种情况 遍历字符串匹配过程中,发现栈里没有我们要匹配的字符,return false
            } else if (st.empty() || st.top() != s[i]) {
    
    
                return false;
            } else {
    
    
                st.pop();
            }
        }
    //第一种情况 遍历完字符串,但是栈不为空,说明有相应的左括号没有右括号来匹配,return false 否则return true
        return st.empty();
    }
};


class Solution {
    
    
public:
    bool isValid(string s) {
    
    
        int size = s.size();
        if (size % 2 == 1) {
    
    
            return false;
        }

        unordered_map<char, char> pairs = {
    
    
            {
    
    ')', '('},
            {
    
    ']', '['},
            {
    
    '}', '{'}
        };
        stack<char> stk;
        for (char ch : s) {
    
    
            if (pairs.count(ch)) {
    
    
                if (stk.empty() || stk.top() != pairs[ch]) {
    
    
                    return false;
                }
                stk.pop();
            } else {
    
    
                stk.push(ch);
            }
        }
        return stk.empty();
    }
};

4. leetcode 1047 删除字符串中的所有相邻重复项

// 相当于匹配
class Solution {
    
    
public:
    string removeDuplicates(string s) {
    
    
        stack<char> st;
        for (auto i : s) {
    
    
            if (st.empty() || i != st.top()) {
    
    
                st.push(i);
            } else (st.pop());
        }

        string res = "";
        while (!st.empty()) {
    
    
            res += st.top();
            st.pop();
        } 
        reverse(res.begin(), res.end());
        return res;
    }
};

5. leetcode 150 逆波兰表达式求值

//使用栈
class Solution {
    
    
public:
    int evalRPN(vector<string>& tokens) {
    
    
        stack<int> st;
        int n = tokens.size();

        for (int i = 0; i < n; i++) {
    
    
            string& token = tokens[i];
            if (isNumber(token)) {
    
    
                st.push(atoi(token.c_str()));
            } else {
    
    
                int num2 = st.top();
                st.pop();
                int num1 = st.top();
                st.pop();
                switch (token[0]) {
    
    
                    case '+':
                        st.push(num1 + num2);
                        break;
                    case '-':
                        st.push(num1 - num2);
                        break;
                    case '*':
                        st.push(num1 * num2);
                        break;
                    case '/':
                        st.push(num1 / num2);
                        break;
                }
            }
        }
        return st.top();
    }

    bool isNumber(string& token) {
    
    
        return !(token == "+" || token == "-" || token == "*" || token == "/");
    }
};


class Solution {
    
    
public:
    int evalRPN(vector<string>& tokens) {
    
    
        stack<int> st;
        for (int i = 0; i < tokens.size(); i++) {
    
    
            if (tokens[i] == "+" || tokens[i] == "-" || tokens[i] == "*" || tokens[i] == "/") {
    
    
                int num2 = st.top();
                st.pop();
                int num1 = st.top();
                st.pop();

                if (tokens[i] == "+") st.push(num1 + num2);
                if (tokens[i] == "-") st.push(num1 - num2);
                if (tokens[i] == "*") st.push(num1 * num2);
                if (tokens[i] == "/") st.push(num1 / num2);
            } else {
    
    
                st.push(stoi(tokens[i]));
            }
        }
        return st.top();
    }
};

//使用数组模拟栈

class Solution {
    
    
public:
    int evalRPN(vector<string>& tokens) {
    
    
        int n = tokens.size();
        vector<int> stk((n + 1) / 2);
        int index = -1;
        for (int i = 0; i < n; i++) {
    
    
            string& token = tokens[i];
            if (token.length() > 1 || isdigit(token[0])) {
    
    
                index++;
                stk[index] = atoi(token.c_str());
            } else {
    
    
                switch (token[0]) {
    
    
                    case '+':
                        index--;
                        stk[index] += stk[index + 1];
                        break;
                    case '-':
                        index--;
                        stk[index] -= stk[index + 1];
                        break;
                    case '*':
                        index--;
                        stk[index] *= stk[index + 1];
                        break;
                    case '/':
                        index--;
                        stk[index] /= stk[index + 1];
                        break;
                }
            }
        }
        return stk[index];
    }
};

6. leetcode 239 滑动窗口最大值

//单调队列 
class Solution {
    
    
private:
    class MyQueue {
    
       //单调队列(从大到小)
    public:
        deque<int> que;  // 通过deque实现单调队列
        
        //每次弹出的时候,比较当前要弹出的数值是否等于队列出口元素的数值,相等则弹出
        //同时pop之前判断队列当前是否为空
        void pop(int val) {
    
    
            if (!que.empty() && val == que.front()) {
    
    
                que.pop_front();
            }
        }

        //如果push的数值大于入口元素,那么将队列后端的数值弹出,直到push的数值小于等于队列入口元素的数值为止
        //这样就保持队列里的数值是单调递减的了
        void push(int val) {
    
    
            while (!que.empty() && val > que.back()) {
    
    
                que.pop_back();
            }
            que.push_back(val);
        }
        //查询当前队列里的最大值
        int front() {
    
    
            return que.front();
        }
    };

public:
    vector<int> maxSlidingWindow(vector<int>& nums, int k) {
    
    
        MyQueue mq;
        vector<int> res;
        //先将前k个元素放进队列
        for (int i = 0; i < k; i++) {
    
    
            mq.push(nums[i]);
        }
        //存储结果
        res.push_back(mq.front());

        for (int i = k; i < nums.size(); i++) {
    
    
            mq.pop(nums[i - k]);  // 滑动窗口移除最前面元素
            mq.push(nums[i]); //加入最后面元素
            res.push_back(mq.front()); //记录最大值
        }
        return res;
    }
};



class Solution {
    
    
public:
    vector<int> maxSlidingWindow(vector<int>& nums, int k) {
    
    
        int n = nums.size();
        deque<int> q;
        for (int i = 0; i < k; ++i) {
    
    
            while (!q.empty() && nums[i] >= nums[q.back()]) {
    
    
                q.pop_back();
            }
            q.push_back(i);
        }

        vector<int> ans = {
    
    nums[q.front()]};
        for (int i = k; i < n; ++i) {
    
    
            while (!q.empty() && nums[i] >= nums[q.back()]) {
    
    
                q.pop_back();
            }
            q.push_back(i);
            while (q.front() <= i - k) {
    
    
                q.pop_front();
            }
            ans.push_back(nums[q.front()]);
        }
        return ans;
    }
};



//优先队列
class Solution {
    
    
public:
    vector<int> maxSlidingWindow(vector<int>& nums, int k) {
    
    
        int n = nums.size();
        priority_queue<pair<int, int>> q;
        for (int i = 0; i < k; ++i) {
    
    
            q.emplace(nums[i], i);
        }
        vector<int> ans = {
    
    q.top().first};
        for (int i = k; i < n; ++i) {
    
    
            q.emplace(nums[i], i);
            while (q.top().second <= i - k) {
    
    
                q.pop();
            }
            ans.push_back(q.top().first);
        }
        return ans;
    }
};


class Solution {
    
    
public:
    vector<int> maxSlidingWindow(vector<int>& nums, int k) {
    
    
        vector<int> ans;  //存放答案,刚开始我把这个写成了vector<int> ans(nums.size()-k+1),然后多了好几个0……
        deque<int> que;   //双向队列,存放nums下标。这个容器有以下操作(看名字就知道作用了):
                          //front(),back(),push_back(value),push_front(value),pop_back(value),pop_front(value)

        // 遍历数组中元素,right表示滑动窗口右边界
        for(int right=0;right<nums.size();right++){
    
    
            // 如果队列不为空且当前考察元素大于等于队尾元素,则将队尾元素移除。
            // 直到,队列为空或当前考察元素小于新的队尾元素
            while(!que.empty()&&nums[que.back()]<=nums[right]){
    
    
                que.pop_back();
            }
            // 存储元素下标
            que.push_back(right);

            // 计算窗口左侧边界
            int left=right-k+1;

            // 当队首元素的下标小于滑动窗口左侧边界left时
            // 表示队首元素已经不再滑动窗口内,因此将其从队首移除
            while(que.front()<left){
    
    
                que.pop_front();
            }

            // 由于数组下标从0开始,因此当窗口右边界right+1大于等于窗口大小k时
            // 意味着窗口形成。此时,队首元素就是该窗口内的最大值
            if(right+1>=k){
    
    
                ans.push_back(nums[que.front()]);
            }
        }
        return ans;
    }
};

猜你喜欢

转载自blog.csdn.net/weixin_44847326/article/details/123533559
今日推荐