【算法篇】栈与队列类(笔记)

目录

一、用栈实现队列

二、用队列实现栈

三、有效的括号

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

五、逆波兰表达式求值

六、滑动窗口最大值  

七、前 K 个高频元素


一、用栈实现队列

232. 用栈实现队列 - 力扣(LeetCode)icon-default.png?t=O83Ahttps://leetcode.cn/problems/implement-queue-using-stacks/description/

        请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(pushpoppeekempty):

实现 MyQueue 类:

  • void push(int x) 将元素 x 推到队列的末尾
  • int pop() 从队列的开头移除并返回元素
  • int peek() 返回队列开头的元素
  • boolean empty() 如果队列为空,返回 true ;否则,返回 false

说明:

  • 你 只能 使用标准的栈操作 —— 也就是只有 push to toppeek/pop from topsize, 和 is empty 操作是合法的。
  • 你所使用的语言也许不支持栈。你可以使用 list 或者 deque(双端队列)来模拟一个栈,只要是标准的栈操作即可。
示例 1:
输入:
["MyQueue", "push", "push", "peek", "pop", "empty"]
[[], [1], [2], [], [], []]
输出:
[null, null, null, 1, 1, false]解释:
MyQueue myQueue = new MyQueue();
myQueue.push(1); // queue is: [1]
myQueue.push(2); // queue is: [1, 2] (leftmost is front of the queue)
myQueue.peek(); // return 1
myQueue.pop(); // return 1, queue is [2]
myQueue.empty(); // return false
class MyQueue {
public:// 定义栈stack<int> Instack;stack<int> Outstack;MyQueue() {}void push(int x) {Instack.push(x);}int pop() {if (Outstack.empty()) {// 输出栈为空while (!Instack.empty()) {Outstack.push(Instack.top());Instack.pop();}}int re = Outstack.top();Outstack.pop();return re;}int peek() {// 使用已有函数int re = this->pop();Outstack.push(re);return re;}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();*/

二、用队列实现栈

225. 用队列实现栈 - 力扣(LeetCode)icon-default.png?t=O83Ahttps://leetcode.cn/problems/implement-stack-using-queues/description/

        请你仅使用两个队列实现一个后入先出(LIFO)的栈,并支持普通栈的全部四种操作(pushtoppop 和 empty)。

实现 MyStack 类:

  • void push(int x) 将元素 x 压入栈顶。
  • int pop() 移除并返回栈顶元素。
  • int top() 返回栈顶元素。
  • boolean empty() 如果栈是空的,返回 true ;否则,返回 false 。

注意:

  • 你只能使用队列的标准操作 —— 也就是 push to backpeek/pop from frontsize 和 is empty 这些操作。
  • 你所使用的语言也许不支持队列。 你可以使用 list (列表)或者 deque(双端队列)来模拟一个队列 , 只要是标准的队列操作即可。
示例:
输入:
["MyStack", "push", "push", "top", "pop", "empty"]
[[], [1], [2], [], [], []]
输出:
[null, null, null, 2, 2, false]解释:
MyStack myStack = new MyStack();
myStack.push(1);
myStack.push(2);
myStack.top(); // 返回 2
myStack.pop(); // 返回 2
myStack.empty(); // 返回 False
class MyStack {
public:queue<int> Inqueue;  // 单队列MyStack() {}void push(int x) {Inqueue.push(x);}int pop() {for (int i = 0; i < Inqueue.size() - 1; i++) {Inqueue.push(Inqueue.front());Inqueue.pop();}int res = Inqueue.front();Inqueue.pop();return res;}int top() {return Inqueue.back();}bool empty() {return Inqueue.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();*/

三、有效的括号

20. 有效的括号 - 力扣(LeetCode)icon-default.png?t=O83Ahttps://leetcode.cn/problems/valid-parentheses/description/

        给定一个只包括 '('')''{''}''['']' 的字符串 s ,判断字符串是否有效。

有效字符串需满足:

  1. 左括号必须用相同类型的右括号闭合。
  2. 左括号必须以正确的顺序闭合。
  3. 每个右括号都有一个对应的相同类型的左括号。
示例 1:
输入: "()"
输出: true示例 2:
输入: "()[]{}"
输出: true示例 3:
输入: "(]"
输出: false示例 4:
输入: "([)]"
输出: false示例 5:
输入: "{[]}"
输出: true

思路:

本题遍历时存在三种情况:

        第一种情况:已经遍历完了字符串,但是栈不为空,说明有相应的左括号没有右括号来匹配,所以 return false

        第二种情况:遍历字符串匹配的过程中,发现栈里没有要匹配的字符。所以 return false

        第三种情况:遍历字符串匹配的过程中,栈已经为空了,没有匹配的字符了,说明右括号没有找到对应的左括号 return false

class Solution {
public:bool isValid(string s) {stack<char> str;for (int i = 0; i < s.length(); i++) {if (s[i] == '(') str.push(')');else if (s[i] == '{') str.push('}');else if (s[i] == '[') str.push(']');// 遍历的过程中栈已经为空,或者不匹配else if (str.empty() || s[i] != str.top()) return false;else str.pop();}return str.empty();}
};

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

1047. 删除字符串中的所有相邻重复项 - 力扣(LeetCode)icon-default.png?t=O83Ahttps://leetcode.cn/problems/remove-all-adjacent-duplicates-in-string/description/

        给出由小写字母组成的字符串 s,重复项删除操作会选择两个相邻且相同的字母,并删除它们。

        在 s 上反复执行重复项删除操作,直到无法继续删除。

        在完成所有重复项删除操作后返回最终的字符串。答案保证唯一。

示例:
输入:"abbaca"
输出:"ca"
解释:例如,在 "abbaca" 中,我们可以删除 "bb" 由于两字母相邻且相同,这是此时唯一可以执行删除操作的重复项。之后我们得到字符串 "aaca",其中又只有 "aa" 可以执行重复项删除操作,所以最后的字符串为 "ca"。
class Solution {
public:string removeDuplicates(string S) {string result;for(char s : S) {if(result.empty() || result.back() != s) {result.push_back(s);}else {result.pop_back();}}return result;}
};

五、逆波兰表达式求值

150. 逆波兰表达式求值 - 力扣(LeetCode)icon-default.png?t=O83Ahttps://leetcode.cn/problems/evaluate-reverse-polish-notation/description/

        给你一个字符串数组 tokens ,表示一个根据 逆波兰表示法 表示的算术表达式。

        请你计算该表达式。返回一个表示表达式值的整数。

注意:

  • 有效的算符为 '+''-''*' 和 '/' 。
  • 每个操作数(运算对象)都可以是一个整数或者另一个表达式。
  • 两个整数之间的除法总是 向零截断 。
  • 表达式中不含除零运算。
  • 输入是一个根据逆波兰表示法表示的算术表达式。
  • 答案及所有中间计算结果可以用 32 位 整数表示。
示例 1:
输入:tokens = ["2","1","+","3","*"]
输出:9
解释:该算式转化为常见的中缀算术表达式为:((2 + 1) * 3) = 9示例 2:
输入:tokens = ["4","13","5","/","+"]
输出:6
解释:该算式转化为常见的中缀算术表达式为:(4 + (13 / 5)) = 6示例 3:
输入:tokens = ["10","6","9","3","+","-11","*","/","*","17","+","5","+"]
输出:22
解释:该算式转化为常见的中缀算术表达式为:((10 * (6 / ((9 + 3) * -11))) + 17) + 5
= ((10 * (6 / (12 * -11))) + 17) + 5
= ((10 * (6 / -132)) + 17) + 5
= ((10 * 0) + 17) + 5
= (0 + 17) + 5
= 17 + 5
= 22
class Solution {
public:int evalRPN(vector<string>& tokens) {stack<long long> record;for (int i = 0; i < tokens.size(); i++) {if (tokens[i] == "+" || tokens[i] == "-" || tokens[i] == "*" || tokens[i] == "/") {long long num1 = record.top(); record.pop();long long num2 = record.top(); record.pop();if (tokens[i] == "+") record.push(num2 + num1);if (tokens[i] == "-") record.push(num2 - num1);if (tokens[i] == "*") record.push(num2 * num1);if (tokens[i] == "/") record.push(num2 / num1);}else {record.push(stoll(tokens[i]));}}return record.top();}
};

六、滑动窗口最大值

239. 滑动窗口最大值 - 力扣(LeetCode)icon-default.png?t=O83Ahttps://leetcode.cn/problems/sliding-window-maximum/description/

        给你一个整数数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。

        返回 滑动窗口中的最大值 。

示例 1:
输入:nums = [1,3,-1,-3,5,3,6,7], k = 3
输出:[3,3,5,5,6,7]
解释:
滑动窗口的位置                最大值
---------------               -----
[1  3  -1] -3  5  3  6  7       31 [3  -1  -3] 5  3  6  7       31  3 [-1  -3  5] 3  6  7       51  3  -1 [-3  5  3] 6  7       51  3  -1  -3 [5  3  6] 7       61  3  -1  -3  5 [3  6  7]      7示例 2:
输入:nums = [1], k = 1
输出:[1]

思路:        

        这是使用单调队列的经典题目。

        队列没有必要维护窗口里的所有元素,只需要维护有可能成为窗口里最大值的元素就可以了,同时保证队列里的元素数值是由大到小的。C++中没有直接支持单调队列,需要我们自己来实现一个单调队列。

设计单调队列的时候,pop 和 push操作要保持如下规则:

  1. pop(value):如果窗口移除的元素value等于单调队列的出口元素,那么队列弹出元素,否则不用任何操作
  2. push(value):如果push的元素value大于入口元素的数值,那么就将队列入口的元素弹出,直到push元素的数值小于等于队列入口元素的数值为止

保持如上规则,每次窗口移动的时候,只要问 que.front() 就可以返回当前窗口的最大值。

        

        具体的请查看网站:代码随想录 (programmercarl.com)

class Solution {
private:class MyQueue { //单调队列(从大到小)public:deque<int> que; // 使用deque来实现单调队列void pop(int value) {// 如果弹出的数值等于队列出口元素的数值,则弹出if (!que.empty() && value == que.front()) {que.pop_front();}}void push(int value) {// 如果push的数值大于入口元素的数值,那么就将队列后端的数值弹出// 这样就保持了队列里的数值是单调从大到小的了while (!que.empty() && value > que.back()) {que.pop_back();}que.push_back(value);}int front() {// front为当前队列里的最大值return que.front();}
};public:vector<int> maxSlidingWindow(vector<int>& nums, int k) {MyQueue que;vector<int> result;// 先将前 k 的元素放进队列for (int i = 0; i < k; i++) { que.push(nums[i]);}// result 记录前 k 的元素的最大值result.push_back(que.front()); for (int i = k; i < nums.size(); i++) {que.pop(nums[i - k]); // 滑动窗口移除最前面元素que.push(nums[i]);    // 滑动窗口前加入最后面的元素result.push_back(que.front()); // 记录对应的最大值}return result;}
};

七、前 K 个高频元素

347. 前 K 个高频元素 - 力扣(LeetCode)icon-default.png?t=O83Ahttps://leetcode.cn/problems/top-k-frequent-elements/description/

        给你一个整数数组 nums 和一个整数 k ,请你返回其中出现频率前 k 高的元素。你可以按 任意顺序 返回答案。

示例 1:
输入: nums = [1,1,1,2,2,3], k = 2
输出: [1,2]示例 2:
输入: nums = [1], k = 1
输出: [1]

思路:

这道题目主要涉及到如下三块内容:

  1. 要统计元素出现频率
  2. 对频率排序
  3. 找出前K个高频元素

        首先统计元素出现的频率,这一类的问题可以使用map来进行统计。

        然后是对频率进行排序,这里我们可以使用一种 容器适配器就是优先级队列。

        缺省情况下priority_queue利用max-heap(大顶堆)完成对元素的排序,这个大顶堆是以vector为表现形式的complete binary tree(完全二叉树)。

        这种场景下,我们只需要维护 k 个 有序的序列 就可以了,所以 使用优先级队列是最优的。

        要用小顶堆,因为要统计最大前k个元素,只有小顶堆每次将最小的元素弹出,最后小顶堆里积累的才是前k个最大元素。

class Solution {
public:struct sortmap {bool operator() (pair<int, int> x, pair<int, int> y) {return x.second > y.second;}};vector<int> topKFrequent(vector<int>& nums, int k) {// 记录频数unordered_map<int, int> map;for (int i = 0; i < nums.size(); i++) {map[nums[i]]++;}// 排序,小顶堆维护前 k 个 mappriority_queue<pair<int, int>, vector<pair<int, int>>, sortmap> record;for (unordered_map<int, int>::iterator it = map.begin(); it != map.end(); it++) {record.push(*it);if (record.size() > k) { record.pop();}}vector<int> result(k);for (int i = k - 1; i >= 0; i--) {result[i] = record.top().first;record.pop();}return result;}
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/144494.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

[PTA]7-6 吃火锅

[PTA]7-6 吃火锅 以上图片来自微信朋友圈&#xff1a;这种天气你有什么破事打电话给我基本没用。但是如果你说“吃火锅”&#xff0c;那就厉害了&#xff0c;我们的故事就开始了。 本题要求你实现一个程序&#xff0c;自动检查你朋友给你发来的信息里有没有 chi1 huo3 guo1。 …

手写Spring

简单实现Spring基于注解配置 ComponentScan Target(ElementType.TYPE) Retention(RetentionPolicy.RUNTIME) public interface ComponentScan {String value() default ""; } 相当于component-scan HspSpringConfig ComponentScan(value "spring.write.com…

两个指令反过来说大模型就理解不了啦?或许该让第三者插足啦 -通过引入中间LLM预处理用户输入以提高多任务处理能力

今天就遇到有点儿dt的问题&#xff0c;利用大模型顺利通了自定义的工具调用&#xff08;并没有用到tools功能&#xff0c;而是通过prompt强制输出&#xff09;&#xff0c;单个单个的没问题哈&#xff0c;但是多个一起就出现问题了 我说“关闭电脑PC1, 打开第2台电脑” 它看不懂…

安卓实现导入Excel文件

使用简化版的jar包 api files(libs/poi-3.12-android-a.jar) api files(libs/poi-ooxml-schemas-3.12-a.jar) 导入遇到了两个兼容问题 1.build.gradle文件里面 android { 要添加 packagingOptions {exclude META-INF/INDEX.LIST } 2.加载大文件要在清单文件里面加androi…

网络变压器HR911130C的使用注意点

HR911130C的使用&#xff0c;需要2个注意点&#xff1a; 1&#xff09;数据线data0、data2、data3是相邻的引脚&#xff0c;但是data1是 不相邻的两个引脚&#xff0c;注意看下面的电路图&#xff0c;所以绘图时需要注意 2&#xff09;LED灯的连接 11脚、12脚&#xff0c;连…

快手可灵AI全球升级1.5模型:引入“运动笔刷”功能 画质大幅提升

9月19日&#xff0c;快手公司宣布其可灵AI模型进行了全球范围内的重磅升级&#xff0c;推出了1.5版本。新版本在多个方面实现了显著提升&#xff0c;包括视频画质、动态效果、美学表现、运动合理性以及语义理解等。 新升级的1.5模型支持在高品质模式下直接输出1080p高清视频&am…

【CSS】一行三个盒子 每个盒子都是16:9

padding-top 属性接受百分比值时,其百分比是基于父元素的宽度来计算的,而不是自身元素的宽度 aspect-ratio 更方便&#xff0c;但存在兼容性问题 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta name&quo…

字符设备驱动 — 4 异常与中断

异常与中断 中断属于异常的一种 异常会直接打断 CPU 的运行&#xff0c;而各种中断会被传到中断控制器&#xff0c;由中断控制器来选择优先级最高的中断并通知 CPU 处理流程 arm 对异常&#xff08;中断&#xff09;处理流程&#xff1a; 初始化&#xff1a; 设置中断源&…

水经微图PC版5.0.0即将内测

让GIS更简单高效&#xff01; 水经微图&#xff08;以下称“微图”&#xff09;PC版5.0.0即将内测&#xff0c;这是一个基于WeMapEngine开发的全新版本。 关于什么是WeMapEngine&#xff0c;请从《WeMapEngine可快速构建的GIS应用功能》一文中了解。 微图5.0.0功能界面 水经…

【分享】“可恶”的运算放大器电容负载

他们说如果使用放大器驱动电容负载(图 1、CLOAD)&#xff0c;一个不错的经验是采用一个 50 或 100 欧的电阻器 (RISO) 将放大器与电容器隔开。这个附加电阻器可能会阻止运算放大器振荡。 图 1.支持电容负载的放大器可能需要在放大器输出与负载电容器之间连接一个电阻器。 使用…

STM32—I2C通信外设

1.I2C外设简介 STM32内部集成了硬件I2C收发电路&#xff0c;可以由硬件自动执行时钟生成、起始终止条件生成、应答位收发、数据收发等功能&#xff0c;减轻CPU的负担支持多主机模型&#xff08;可变多主机&#xff09;支持7位/10位地址模式&#xff08;11110......)支持不同的通…

JavaWeb JavaScript 11.XML —— 配置文件

生活想埋没我&#xff0c;没想到我是颗种子 —— 24.9.19 一、XML 1.什么是XML XML是EXtensible Markup Languge的缩写&#xff0c;翻译过来就是可扩展标记语言。所以很明显&#xff0c;XML和HTML一样都是标记语言&#xff0c;也就是说它们的基本语法都是标签 可扩展 三个字…

OpenCV基础入门30讲(Python)——第二讲 图像色彩转换

常见的几种颜色类型介绍 1、彩色图像&#xff08;Color Image&#xff0c;BGR&#xff09; 数据类型&#xff1a;uint8通道数&#xff1a;3&#xff08;BGR&#xff1a;蓝色、绿色、红色&#xff09;描述&#xff1a;彩色图像有三个通道&#xff0c;每个通道的值范围是 0 到 …

【图书推荐】《Autodesk Inventor 2024入门与案例实战(视频教学版)》

本书重点 配套示例文件、PPT课件、教学视频、电子教案、课程标准、骄婿大纲、模拟试题、作者微信群答疑服务。 内容简介 《Autodesk Inventor 2024入门与案例实战&#xff1a;视频教学版》以Autodesk Inventor 2024为平台&#xff0c;重点介绍Autodesk Inventor 2024中文版的…

洗衣机制造5G智能工厂物联数字孪生平台,推进制造业数字化转型

洗衣机制造业作为传统制造业的重要组成部分&#xff0c;通过引入5G智能工厂物联数字孪生平台&#xff0c;加速推进自身的数字化转型进程。这一创新模式不仅极大地提升了生产效率&#xff0c;还深刻改变了产品的设计、生产、管理及运维流程&#xff0c;为行业带来了前所未有的竞…

[数据集][目标检测]手机识别检测数据集VOC+YOLO格式9997张1类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;9997 标注数量(xml文件个数)&#xff1a;9997 标注数量(txt文件个数)&#xff1a;9997 标注…

saltstack企业实战

saltstack官网最新文档 saltstack架构设计 saltstack 高可用方案&#xff1a;Salt官网是有 HARebalance minion配置里写多个master地址 failover&#xff08;syndic&#xff09; 架构 操作系统&#xff1a;CentOS7.6salt版本&#xff1a;3000.3 多master https://www.cn…

【贪心算法】贪心算法一

贪心算法一 1.柠檬水找零2.将数组和减半的最少操作次数3.最大数4.摆动序列 点赞&#x1f44d;&#x1f44d;收藏&#x1f31f;&#x1f31f;关注&#x1f496;&#x1f496; 你的支持是对我最大的鼓励&#xff0c;我们一起努力吧!&#x1f603;&#x1f603; 1.柠檬水找零 题目…

【2023工业异常检测文献】SimpleNet

SimpleNet:ASimpleNetworkforImageAnomalyDetectionandLocalization 1、Background 图像异常检测和定位主要任务是识别并定位图像中异常区域。 工业异常检测最大的难题在于异常样本少&#xff0c;一般采用无监督方法&#xff0c;在训练过程中只使用正常样本。 解决工业异常检…

无人机黑飞打击技术详解

随着无人机技术的普及&#xff0c;无人机“黑飞”&#xff08;未经授权或违反规定的飞行&#xff09;现象日益严重&#xff0c;对公共安全、隐私保护及重要设施安全构成了严重威胁。为有效应对这一挑战&#xff0c;各国政府和安全机构纷纷研发并部署了一系列无人机黑飞打击技术…