首页 > 其他分享 >代码随想录刷题记录——栈与队列篇

代码随想录刷题记录——栈与队列篇

时间:2023-09-08 16:56:07浏览次数:42  
标签:队列 随想录 pop st int que push 刷题

栈与队列理论基础

  •  栈stack:先进后厨
  • 队列queue:先进先出
  • STL(C++标准库)
  • STL 栈和队列属于容器适配器(container adapter)
  • 优先队列priority_queue:
    • 默认大根堆,如果是pair<a,b>,默认比较a大小
    • 如果需要比较b大小,且小根堆,可以如下实现

232.用栈实现队列

题目链接

  •  pop操作时,当out栈为空时,需要将in栈全部取出并放入out
#include<bits/stdc++.h>
using namespace std;

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

    }
    
    void push(int x) {
        stIn.push(x);
    }
    
    int pop() {
        //只有Out栈为空时,需要把In栈全部放到Out栈
        if(stOut.empty()){
            while(!stIn.empty()){
            stOut.push(stIn.top());
            stIn.pop();
            }
        }       
        int a = stOut.top();
        stOut.pop();
        return a;
    }
    
    int peek() {
        int a = this->pop();
        stOut.push(a);
        return a;
    }
    
    bool empty() {
        return stIn.empty()&&stOut.empty();
    }
};

 

 

225. 用队列实现栈

题目链接

  • pop操作时,把除最后一个元素外所有元素取出队列再放进,此时再取出下一个元素即模拟可栈后进先出。
#include<bits/stdc++.h>
using namespace std;

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

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

 

 

20. 有效的括号

题目链接

#include<bits/stdc++.h>
using namespace std;

class Solution {
public:
    bool isValid(string s) {
        stack<char> 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(']');
            else if(st.empty()||s[i]!=st.top()) return false;
            else    st.pop();
        } 
        return st.empty();
    }
};

 

删除字符串中的所有相邻重复项

题目链接

#include<bits/stdc++.h>
using namespace std;

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.push(s[i]);
            else    st.pop();
        }
        string ans = "";
        while(!st.empty()){
            ans += st.top();
            st.pop();
        }
        reverse(ans.begin(),ans.end());
        return ans;
    }
};
  • C++中,std::string类提供类似入栈、出栈接口
class Solution {
public:
    string removeDuplicates(string s) {
        string stk;
        for (char ch : s) {
            if (!stk.empty() && stk.back() == ch) {
                stk.pop_back();
            } else {
                stk.push_back(ch);
            }
        }
        return stk;
    }
};

 

 

 

150. 逆波兰表达式求值

题目链接

#include<bits/stdc++.h>
using namespace std;

class Solution {
public:
    int evalRPN(vector<string>& tokens) {
        stack<int> st;
        for(string token: tokens){
            if(token!="+"&&token!="-"&&token!="*"&&token!="/"){
                int t = stoi(token);//stoi函数,string to int 缩写
                st.push(t);
            }
            else{
                int num1 = st.top();
                st.pop();
                int num2 = st.top();
                st.pop();
                if(token=="+")  st.push(num2+num1);
                if(token=="-")  st.push(num2-num1);
                if(token=="*")  st.push(num2*num1);
                if(token=="/")  st.push(num2/num1);
            }
        }
        int ans = st.top();
        st.pop();
        return ans;
    }
};

 

 

239. 滑动窗口最大值

题目链接

  • 优先队列priority_queue
  • 需要存下标,判断是否在窗口内
#include<bits/stdc++.h>
using namespace std;

class Solution {
public:
    vector<int> maxSlidingWindow(vector<int>& nums, int k) {
        priority_queue<pair<int, int>> que;//pair<nums[i], i>
        for(int i=0;i<k;i++){
            que.emplace(nums[i], i);
        }
        vector<int> ans = {que.top().first};
        //开始滑动
        for(int i=k;i<nums.size();i++){
            que.emplace(nums[i], i);
            //当优先队列队首值(最大值)index没在窗口范围内,出队列,保证最大值索引在窗口内
            while(que.top().second<=i-k){
                que.pop();
            }
            ans.push_back(que.top().first);
        }
        return ans;
    }
};

 

 

  • 单调队列
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;
    }
};

 

 

347.前 K 个高频元素

题目链接

  • 使用优先队列定义小根堆并自定义比较方式时需注意:
    • priority_queue<pair<int, int>, vector<pair<int, int>>, decltype(&cmp)> minHeap(cmp);
    • static bool cmp(pair<int, int> &m, pair<int, int> &n)
    • 即decltype(&cmp)里的‘&’不能少,且cmp函数需要是static静态函数,否则decltype推断时报错
#include<bits/stdc++.h>
using namespace std;

class Solution {
public:
    static bool cmp(pair<int, int> &m, pair<int, int> &n) {
        return m.second > n.second;
    }

    vector<int> topKFrequent(vector<int>& nums, int k) {
        priority_queue<pair<int, int>, vector<pair<int, int>>, decltype(&cmp)> minHeap(cmp);//小根堆
        unordered_map<int, int> map;
        for(int i=0;i<nums.size();i++){
            map[nums[i]]++;
        }
        for(auto it: map){
            if(minHeap.size()==k){
                if(minHeap.top().second<it.second){
                    minHeap.pop();
                    minHeap.emplace(it.first, it.second);
                }
            }
            else{
                minHeap.emplace(it.first, it.second);
            }
        }
        vector<int> ans;
        while(!minHeap.empty()){
            ans.push_back(minHeap.top().first);
            minHeap.pop();
        }
        return ans;
    }
};

 

 

栈与队列总结篇

  • 站和队列是容器适配器
  • 默认情况下栈和队列的底层容器是deque双端队列,
  • 栈的经典应用:括号匹配、逆波兰表达式
  • 队列经典应用:滑动窗口最大值(单调队列)、求前k个高频元素(优先级队列)

 

标签:队列,随想录,pop,st,int,que,push,刷题
From: https://www.cnblogs.com/daxiawan2022/p/17686132.html

相关文章

  • 线程安全的队列:使用Monitor模式和C++11多线程库
    线程安全的队列:使用Monitor模式和C++11多线程库引言在多线程编程中,数据共享是一个关键的问题。如果多个线程需要访问同一个数据结构,不正确的管理会导致数据不一致甚至程序崩溃。本文将介绍如何使用C++11的多线程库和Monitor模式来实现一个线程安全的队列。Monitor模式Monitor模式......
  • 代码随想录算法训练营第二天| 977.有序数组的平方,209.长度最小的子数列,59.螺旋矩阵Ⅱ
    977.有序数组的平方双指针法因为负数平方后也会变大,所以较大的平方值只可能在靠近两端的位置,越往中间走平方值必定越小。所以,在原数组两端各定义一个指针,慢慢往中间走,然后把平方值按顺序放到新数组里即可。classSolution{public:vector<int>sortedSquares(vector<i......
  • 深入理解消息队列与事件驱动架构
    什么是消息队列?消息队列是一种通信模式,用于将消息从一个发送者传递到一个或多个接收者。它们允许应用程序之间以异步、松耦合的方式进行通信。消息队列通常包括消息代理(如RabbitMQ、ApacheKafka)和消息消费者。为什么使用消息队列?使用消息队列的好处包括:解耦应用程序:消息队列允许......
  • python:列表实现队列​
    什么是队列队列是一种先进先出的数据结构,类似食堂排队打饭,先入队的元素当然要先出队,先请用Python列表模拟队列。现有一列表queue=[1,2,3,4,5]被视作队列,请使用pop函数连续两次取出队首元素,再使用append函数将输入元素添加到队尾,每次操作后都要输出完整的列表。功能需求输入......
  • 代码随想录刷题记录——双指针篇
    27.移除元素题目链接快慢指针,最终返回index值为移除元素后的数组末尾元素下标+1.#include<vector>usingnamespacestd;classSolution{public:intremoveElement(vector<int>&nums,intval){//快慢指针intnums_length=nums.size();......
  • 代码随想录个人笔记——字符串篇
    344.反转字符串 题目链接#include<bits/stdc++.h>usingnamespacestd;classSolution{public:voidreverseString(vector<char>&s){intlen=s.size();for(inti=0,j=len-1;i<j;i++,j--){//第一种//i......
  • 代码随想录算法训练营第二天
    代码随想录算法训练营第二天|LeetCode977(有序数组的平方)LeetCode209(长度最小的子数组)LeetCode59(螺旋矩阵II)977:有序数组的平方LeetCode977(有序数组的平方)思路:方法一:暴力方法直接原地平方后,直接调用数组排序方法二:双指针前后遍历,构造结果数组,保证有序方法......
  • 数据结构代码题-栈、队列
    目录栈、队列栈队列栈和队列的应用栈、队列栈栈的定义#defineMaxSize100//储存空间的初始分配量typedefintElemType;typedefstruct{inttop;//栈顶指针ElemTypedata[MaxSize];//存放元素的动态数组空间}sqstack;链栈的数据结构描述type......
  • 【刷题笔记】
    题目Givenacollectionofcandidatenumbers(candidates)andatargetnumber(target),findalluniquecombinationsin candidates wherethecandidatenumberssumsto target.Eachnumberin candidates mayonlybeused once inthecombination.Note:All......
  • 代码随想录算法第一天704
    代码随想录算法第一天|704.二分查找、27.移除元素学习(复习)数组理论基础:​ (https://programmercarl.com/数组理论基础.html)​ 新了解到Java中数组地址不是连续的。704.二分查找题目题目链接:https://leetcode.cn/problems/binary-search/文章讲解:https://programmercarl.......