代码随想录笔记--栈与队列篇

目录

1--用栈实现队列

2--用队列实现栈

3--有效的括号

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

5--逆波兰表达式求值

6--滑动窗口的最大值

7--前k个高频元素


1--用栈实现队列

利用两个栈,一个是输入栈,另一个是输出栈

#include <iostream>
#include <stack>class MyQueue {
public:MyQueue() {}void push(int x) {in_stk.push(x);}int pop() {if(out_stk.empty()){while(!in_stk.empty()){out_stk.push(in_stk.top());in_stk.pop();}}int tmp = out_stk.top();out_stk.pop();return tmp;}int peek() {if(out_stk.empty()){while(!in_stk.empty()){out_stk.push(in_stk.top());in_stk.pop();}}return out_stk.top();}bool empty() {if(out_stk.empty() && in_stk.empty()) return true;else return false;}
private:std::stack<int> in_stk, out_stk;
};int main(int argc, char* argv[]){MyQueue Queue;Queue.push(1);Queue.push(2);Queue.push(3);std::cout << Queue.pop() << std::endl;std::cout << Queue.peek() << std::endl;return 0;
}

2--用队列实现栈

主要思路:

        弹出栈顶元素时,需要将队列前 size - 1 个元素先弹出再重新加入到队列中;

#include <iostream>
#include <queue>class MyStack {
public:MyStack() {}void push(int x) {q.push(x);}int pop() {int size = q.size();for(int i = 1; i <= size - 1; i++){q.push(q.front());q.pop();}int tmp = q.front();q.pop();return tmp;}int top() {int size = q.size();for(int i = 1; i <= size - 1; i++){q.push(q.front());q.pop();}int tmp = q.front();q.pop();q.push(tmp);return tmp;}bool empty() {return q.empty();}
private:std::queue<int> q;
};int main(int argc, char* argv[]){MyStack stk;stk.push(1);stk.push(2);stk.push(3);std::cout << stk.pop() << std::endl;std::cout << stk.top() << std::endl;return 0;
}

3--有效的括号

主要思路:

        基于栈,遇到左括号,入栈对应的右括号。遇到右括号,判断当前栈顶元素是否与右括号相等,相等则表示之前曾遇到对应的左括号,表明匹配成功并弹出栈顶元素,否则返回 false;

        最后判断栈是否为空,即是否有未匹配的左括号;

#include <iostream>
#include <stack>
#include <string>class Solution {
public:bool isValid(std::string s) {std::stack<char> stk;for(int i = 0; i < s.length(); i++){if(s[i] == '(') stk.push(')');else if(s[i] == '[') stk.push(']');else if(s[i] == '{') stk.push('}');else{if(stk.empty()) return false;else if(stk.top() != s[i]) return false;else stk.pop(); // 匹配}}return stk.empty();}
};int main(int argc, char* argv[]){std::string test = "()[]{}";Solution S1;bool res = S1.isValid(test);if(res) std::cout << "true" << std::endl;else std::cout << "false" << std::endl;return 0;
}

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

主要思路:

        基于栈,遍历字符串,判断当前字符与栈顶元素是否相同,相同则弹出栈顶元素,否则入栈;

        最后遍历栈,将栈内的元素重构为字符串,需注意顺序;

#include <iostream>
#include <stack>
#include <string>class Solution {
public:std::string removeDuplicates(std::string s) {std::stack<char> stk;for(int i = 0; i < s.length(); i++){if(stk.empty() || stk.top() != s[i]){stk.push(s[i]);}else{ // s[i] == stk.top()stk.pop();}}std::string res;while(!stk.empty()){res = stk.top() + res;stk.pop();}return res;}
};int main(int argc, char* argv[]){std::string test = "abbaca";Solution S1;std::string res = S1.removeDuplicates(test);std::cout << res << std::endl;return 0;
}

5--逆波兰表达式求值

主要思路:

        基于栈,遍历字符串数组,当遇到数字时将数字压入栈中,当遇到运算符时,将栈顶的两个元素取出来进行运算,并将运算结果重新压入栈中;

        需注意运算顺序,即第二个出栈的 num2 作为运算符的左侧元素;

#include <iostream>
#include <vector>
#include <stack>
#include <string>class Solution {
public:int evalRPN(std::vector<std::string>& tokens) {std::stack<int> stk;for(int i = 0; i < tokens.size(); i++){if(tokens[i] != "+" && tokens[i] != "-" && tokens[i] != "*" && tokens[i] != "/"){stk.push(std::stoi(tokens[i]));continue;}int num1 = stk.top();stk.pop();int num2 = stk.top();stk.pop();if(tokens[i] == "+"){  int num3 = num2 + num1;stk.push(num3);continue;}else if(tokens[i] == "-"){int num3 = num2 - num1;stk.push(num3);continue;}else if(tokens[i] == "*"){int num3 = num2 * num1;stk.push(num3);continue;                }else{int num3 = num2 / num1;stk.push(num3);continue;}}return stk.top();}
};int main(int argc, char* argv[]){// tokens = ["2","1","+","3","*"]std::vector<std::string> test = {"2", "1", "+", "3", "*"};Solution S1;int res = S1.evalRPN(test);std::cout << res << std::endl;return 0;
}

6--滑动窗口的最大值

主要思路:

        维护一个双端队列,队列里的元素存储的是可能成为最大值的元素,对于当前滑动窗口,其最大值为队头元素;

        当移动滑动窗口时,需要判断当前移出窗口的元素是否是队头元素,如果是则需先将队头元素弹出(因为该元素已经离开了滑动窗口,相当于失效);

        之前本题的解法是存储元素的索引(之前的解法),这样可以避免重复元素的出现;但现在本题的解法是存储元素,所以一个细节是需要避免错误移除重复元素的问题,具体可以推导例子:[-7,-8,7,5,7,1,6,0];

#include <iostream>
#include <vector>
#include <queue>class Solution {
public:std::vector<int> maxSlidingWindow(std::vector<int>& nums, int k) {std::deque<int> q; // 存储可能成为最大值的元素std::vector<int> res;// 初始化第一个滑动窗口for(int i = 0; i < k; i++){// 不能取等于号的原因是可能会出现相等的数,例如下例// [-7,-8,7,5,7,1,6,0] 出现了两个7,取=号会误弹出第2个7while(!q.empty() && q.back() < nums[i]){q.pop_back();}q.push_back(nums[i]);}res.push_back(q.front());// 遍历更新for(int i = k; i < nums.size(); i++){// 移除滑动窗口左边界的元素if(nums[i-k] == q.front()) q.pop_front();// 把不可能成为最大值的元素从队列中移出while(!q.empty() && q.back() < nums[i]){q.pop_back();}q.push_back(nums[i]);res.push_back(q.front()); // 记录当前滑动窗口的最大值}return res;}
};int main(int argc, char* argv[]){std::vector<int> test = {1, 3, -1, -3, 5, 3, 6, 7};int k = 3;Solution S1;std::vector<int> res = S1.maxSlidingWindow(test, k);for(auto v : res) std::cout << v << " ";std::cout << std::endl;return 0;
}

7--前k个高频元素

主要思路:

        维护一个优先队列(小顶堆),里面存储 k 个元素及其出现的次数;

#include <iostream>
#include <vector>
#include <map>
#include <queue>class Solution {
public:std::vector<int> topKFrequent(std::vector<int>& nums, int k) {std::map<int, int> m;for(int i = 0; i < nums.size(); i++){m[nums[i]] += 1;}// 小顶堆std::priority_queue<std::pair<int, int>, std::vector<std::pair<int, int>>, mycompare> pri_q;for(auto it = m.begin(); it != m.end(); it++){pri_q.emplace(*it);if(pri_q.size() > k) pri_q.pop(); // 始终维护 k 个 pair 对}// 倒叙输出k个高频元素std::vector<int> res(pri_q.size(), 0);for(int i = pri_q.size() - 1; i>=0; i--){res[i] = pri_q.top().first;pri_q.pop();}return res;}class mycompare{public:bool operator()(std::pair<int, int>& item1, std::pair<int, int>& item2){return item1.second > item2.second;}};
};int main(int argc, char* argv[]){// nums = [1,1,1,2,2,3], k = 2std::vector<int> test = {1, 1, 1, 2, 2, 3};int k = 2;Solution S1;std::vector<int> res = S1.topKFrequent(test, k);for(auto item : res) std::cout << item << " ";std::cout << std::endl;return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何把本地项目上传github

一、在gitHub上创建新项目 【1】点击添加&#xff08;&#xff09;-->New repository 【2】填写新项目的配置项 Repository name&#xff1a;项目名称 Description &#xff1a;项目的描述 Choose a license&#xff1a;license 【3】点击确定&#xff0c;项目已在githu…

前几天写的博客被选中进入【CSDN月度精选】榜单

小收获&#xff0c;记录一下&#xff0c;哈哈 这个貌似是CSDN给的排名和得分&#xff1a;

政府科技项目验收全流程分享

科技验收测试 &#xff08;验收申请→主管部门初审→科技厅审核→组织验收→归档备案→信用管理&#xff09;&#xff1a; &#xff08;一&#xff09;验收申请 项目承担单位通过省科技业务管理系统提交验收申请。 按期完成的项目&#xff0c;项目承担单位应当在项目合同书…

【数据库】关系模型介绍+形式化关系查询语言

目录 第2章 关系模型介绍 2.1 关系数据库的结构 关系 2.2 数据库模式 2.3 码 2.4 模式图 大学数据库的模式图&#xff01;&#xff01;&#xff01; 大学数据库关系模式&#xff01;&#xff01;&#xff01; 2.5 关系查询语言 2.6 关系运算 2. 7 总结 第6章 形式化…

【分布式搜索引擎elasticsearch】

文章目录 1.elasticsearch基础索引和映射索引库操作索引库操作总结 文档操作文档操作总结 RestAPIRestClient操作文档 1.elasticsearch基础 什么是elasticsearch&#xff1f; 一个开源的分布式搜索引擎&#xff0c;可以用来实现搜索、日志统计、分析、系统监控等功能 什么是…

docker安装jenkins

运行jenkins docker run -d \--name jenkins \ --hostname jenkins \-u root \-p 29090:8080 \--restart always \-v D:\springcloud\学习\jekins\jenkins\jks_home:/var/jenkins_home \ jenkins/jenkins获取root登录密码 密码在jekins_home/secrets/initalAdminPassword文件…

LLM - LLaMA-2 获取文本向量并计算 Cos 相似度

目录 一.引言 二.获取文本向量 1.hidden_states 与 last_hidden_states ◆ hidden_states ◆ last_hidden_states 2.LLaMA-2 获取 hidden_states ◆ model config ◆ get Embedding 三.获取向量 Cos 相似度 1.向量选择 2.Cos 相似度 3.BERT-whitening 特征白化 …

python数据分析基础—pandas中set_index()、reset_index()的使用

文章目录 一、索引是什么&#xff1f;二、set_index()三、reset_index() 一、索引是什么&#xff1f; 在进行数据分析时&#xff0c;通常我们要根据业务情况进行数据筛选&#xff0c;要求筛选特定情况的行或列&#xff0c;这时就要根据数据类型(Series或者DataFrame)的索引情况…

短信验证码服务

使用的是 阿里云 阿里云官网 1.找到 左上角侧边栏 -云通信 -短信服务 2.在快速学习测试处 &#xff0c;按照步骤完成快速学习&#xff0c;绑定要测试的手机号&#xff0c;选专用 【测试模板】&#xff0c;自定义模板需要人工审核&#xff0c;要一个工作日 3.右上角 获取 Acces…

Revit SDK:AutoParameter 添加参数

前言 这个例子介绍如果往族文件里添加参数。 内容 Revit 的参数&#xff0c;参考官方文档&#xff1a; 这个例子的关键接口&#xff1a; // 通过 FamilyManager 添加参数 FamilyParameter AddParameter(string parameterName, BuiltInParameterGroup parameterGroup, Categ…

matlab绘制局部放大图

ZoomPlot是一个交互式的matlab局部绘图库&#xff0c;其github仓库地址为 https://github.com/iqiukp/ZoomPlot-MATLAB。在使用库之前需要先将库下载到本地&#xff0c;可以直接添加到matlab的库中&#xff0c;也可以放在项目文件中直接使用。 简单使用 其实使用这个库只需要…

CocosCreator3.8研究笔记(三)CocosCreator 项目结构说明及编辑器的简单使用

我们通过Dashboard 创建一个2d项目&#xff0c;来演示CocosCreator 的项目结构。 等待创建完成后&#xff0c;会得到以下项目工程&#xff1a; 一、assets文件夹 assets文件夹&#xff1a;为资源目录&#xff0c;用来存储所有的本地资源&#xff0c;如各种图片&#xff0c;脚本…