当前位置: 首页 > news >正文

4.23刷题记录(栈与队列专题)

第一部分:基础知识

  1. 栈先进后出,队列先进先出
  2. 栈用stack实现,主要函数有pop,push,top
  3. 队列由queue或者deque实现,主要函数有front,back,push,pop,emplace(在队尾直接加一个元素)

第二部分:习题部分

(1)232. 用栈实现队列 - 力扣(LeetCode)

本题比较简单,只需要通过两个栈相互替换数据即可。

其中感觉比较巧妙的就是判断second是否为空,从而判断是否需要倒置

class MyQueue {
public:stack<int>first;stack<int>second;MyQueue() {}void push(int x) {first.push(x);return;}int pop() {//注意此处弹出的是压在栈底的东西int x;if(second.empty()){while(!first.empty()){x=first.top();first.pop();second.push(x);}}x=second.top();second.pop();return x;}int peek() {int x;if(second.empty()){while(!first.empty()){x=first.top();first.pop();second.push(x);}}x=second.top();return x;}bool empty() {return first.empty()&&second.empty();}
};

(2)225. 用队列实现栈 - 力扣(LeetCode)

解题思路:此题目比较简单,仅需要对pop操作时候注意简化,将第一个队列中的全部元素拷贝到第二个队列中,并且将第一个剩余的弹出并保存返回,然后swap即可得到所需要的新的first

class MyStack {
public:queue<int>first;queue<int>second;MyStack() {}void push(int x) {first.push(x);}int pop() {//首先这里要进行判断的while(!first.empty()&&first.size()>1){second.push(first.front());first.pop();}int k=first.front();first.pop();swap(first,second);return k;}int top() {int x=this->pop();first.push(x);return x;}bool empty() {return first.empty()&&second.empty();}
};

(3)20. 有效的括号 - 力扣(LeetCode)

解题思路:本题目比较简单,需要考虑几种特殊情况

  1. 如果括号的数量是奇数,那么肯定不可能匹配成功
  2. 如果括号栈中最后还剩余,肯定不可能返回true
  3. 如果一左一右括号匹配不上,则直接返回flase
class Solution {
public:bool isValid(string s) {int n=s.size();if(n==0||n%2==1)return false;stack<char>stack;for(int i=0;i<s.size();i++){if(s[i]=='(')stack.push(')');else if(s[i]=='[')stack.push(']');else if(s[i]=='{')stack.push('}');else{if(stack.empty()||s[i]!=stack.top()){return false;}stack.pop();}}return stack.empty()==1;}
};

(4)1047. 删除字符串中的所有相邻重复项 - 力扣(LeetCode)

本题思路:如果遇到两个一样的则弹出,最后将栈中的元素进行翻转

class Solution {
public:string removeDuplicates(string s) {stack<char>stack;for(int i=0;i<s.size();i++){if(stack.empty()||s[i]!=stack.top()){stack.push(s[i]);continue;}else{stack.pop();}}string ans;while(!stack.empty()){ans+=stack.top();stack.pop();}reverse(ans.begin(),ans.end());return ans;}
};

(5)150. 逆波兰表达式求值 - 力扣(LeetCode)

真题思路比较简单,可以直接秒掉

class Solution {
public:int evalRPN(vector<string>& tokens) {stack<long long>operate;int n=tokens.size();for(int i=0;i<n;i++){//如果不是操作符则直接入栈if(tokens[i] != "+" && tokens[i] != "-" && tokens[i] != "*" && tokens[i] != "/"){operate.push(stoll(tokens[i]));}//如果是操作符则弹出运算else{long long num1=operate.top();operate.pop();long long num2=operate.top();operate.pop();if (tokens[i] == "+") operate.push(num2 + num1);if (tokens[i] == "-") operate.push(num2 - num1);if (tokens[i] == "*") operate.push(num2 * num1);if (tokens[i] == "/") operate.push(num2 / num1);}}return operate.top();}
};

(6)239. 滑动窗口最大值 - 力扣(LeetCode)

解题思路:用到了单调队列

  1. 注意两点:首先这个单调队列如何维护:不断存放更小值,如果遇到更大的值的话队首会被弹出。
  2. 检测队首的是否在这个区间内,用一个if就可以
  3. 最后必须i>=k-1的时候才允许加入,否则会出现第一二个元素,他不是范围内的最大值,但是他也加进去了。
class Solution {
public:vector<int> maxSlidingWindow(vector<int>& nums, int k) {//1,初始化vector<int>ans;deque<int>deq;//2.维护单调队列for(int i=0;i<nums.size();i++){//首先弹出超出范围的数值if(!deq.empty()&&deq.front()==i-k){deq.pop_front();}//维护单调队列while(!deq.empty()&&nums[i]>nums[deq.back()]){deq.pop_back();}//构造窗口deq.push_back(i);//加入结果if(i>=k-1){ans.push_back(nums[deq.front()]);}}return ans;}
};

(7)347. 前 K 个高频元素 - 力扣(LeetCode)

解题思路:堆

  1. 堆的三个元素分别为:存储变量,底层实现容器,比较逻辑。第一个比较简单,第二个直接在前面加vector<>即可,第三个比较逻辑可以通过static bool cmp设置一个函数,然后通过decltype(&cmp)来更改比较逻辑。也可以通过构造一个struct重载运算符。
  2. 构造完最大堆后,只需要不断弹出顶部元素即可。
class Solution {
public://第二种构造方法的structstruct ComparePerson {bool operator()(const pair<int,int>& a, const pair<int,int>& b) {return a.second < b.second; // 最大堆(如果比较函数返回 true,则表示第一个参数(a)应该排在第二个参数(b)的前面。//如果比较函数返回 false,则表示第一个参数(a)应该排在第二个参数(b)的后面。//这里面其实想放的是b的频率更大,所以应该返回true,所以a就放在了b的前面,//然后优先队列优先构造底部,所以a频率小的就在底部,顶部就是最大值。}};// 自定义比较函数,用于优先队列static bool cmp(const pair<int, int>& a, const pair<int, int>& b) {return a.second < b.second; // 用于最大堆}vector<int> topKFrequent(vector<int>& nums, int k) {unordered_map<int, int> cnt; // 用于统计每个数字的频率vector<int> ans; // 存储结果// 统计每个数字的频率for (int num : nums) {cnt[num]++;}// 构造最大堆priority_queue<pair<int, int>, vector<pair<int, int>>, decltype(&cmp)> maxHeap(cmp);//第二种构造方法//priority_queue<pair<int, int>, vector<pair<int, int>>, ComparePerson> maxHeap;//插入元素for(auto item:cnt){maxHeap.push(item);}//取出元素while(k>0&&!maxHeap.empty()){auto item=maxHeap.top();ans.push_back(item.first);maxHeap.pop();k--;}return ans;}
};

http://www.xdnf.cn/news/99865.html

相关文章:

  • devops自动化容器化部署
  • 【人工智能】解锁 AI 潜能:DeepSeek 大模型迁移学习与特定领域微调的实践
  • MCP 协议:AI 时代的 “USB-C” 革命——从接口统一到生态重构的技术哲学
  • 硬核解析:整车行驶阻力系数插值计算与滑行阻力分解方法论
  • vue项目打包后点击dist下面index.html(无法访问您的文件该文件可能已被移至别处、修改或删除。ERR_FILE_NOT_FOUND)比如若依
  • 金仓读写分离集群修改IP
  • 从性能到安全:大型网站系统架构演化的 13 个核心维度
  • Qt案例 使用QFtpServerLib开源库实现Qt软件搭建FTP服务器,使用QFTP模块访问FTP服务器
  • C语言中小写字母转大写字母
  • 数据通信学习笔记之OSPF的基础术语
  • 有哪些信誉良好的脂多糖供应商推荐?
  • 16.第二阶段x64游戏实战-分析二叉树结构
  • 前端js需要连接后端c#的wss服务
  • python自动化测试1——鼠标移动偏移与移动偏移时间
  • Redis 服务自动开启
  • Linux——进程优先级/切换/调度
  • Elasticsearch 堆内存使用情况和 JVM 垃圾回收
  • Maven 项目中引入本地 JAR 包
  • LinkedList与链表
  • 论文阅读 | 大模型工具调用控制的策略优化
  • Centos9安装docker
  • (20)VTK C++开发示例 --- 读取 DEM(高程地图)文件
  • 科学养生,拥抱健康生活
  • 电脑如何监控?六个电脑监控方法分享,请查收
  • 基于大模型的胃食管反流病全周期预测与诊疗方案研究
  • 【重学Android】03.高版本 Android Studio 不能使用引用库资源ID的问题
  • 服务器上部署Nginx的几种方式
  • vant Dialog组件调用的坑
  • Linux : 理解文件系统
  • CentOS 系统 DeepSeek 部署