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

【力扣刷题篇】栈与队列相关OJ题及题解

数据结构之栈 力扣OJ题型一览

    • 20 . 有效的括号
      • 1> 题目介绍
      • 2> 题目解析
      • 3> 题解
        • 思路一 -- 依次遍历栈顶元素, 采取键值匹配的形式
    • 225 . 用队列实现栈
      • 1 . 题目介绍
      • 2 . 题目解析
      • 3 . 题解
        • 思路一 -- 双队列实现栈
        • 思路二 -- 单队列实现栈
    • 232 . 用栈实现队列
      • 1 . 题目介绍
      • 2 . 本题要求
      • 3 . 题解
        • 思路一 -- 单栈模拟队列的进或出
        • 思路一 -- 代码优化
    • 622 . 设计循环队列
      • 1 . 题目描述
      • 2 . 题目解析
      • 3 . 题解
        • 思路一 -- n+1个空间实现n个有效长度

20 . 有效的括号

1> 题目介绍

给定一个只包括 ‘(’,’)’,’{’,’}’,’[’,’]’ 的字符串 s ,判断字符串是否有效。
有效字符串需满足:

  • 左括号必须用相同类型的右括号闭合。
  • 左括号必须以正确的顺序闭合。
  • 每个右括号都有一个对应的相同类型的左括号。

2> 题目解析

条件一 指: 左右括号类型必须一致。 例如左括号是圆括号 ( , 那么其对于的右括号也必须是 )
条件二指: 左右括号的内外顺序必须一致, 也就是由外向内的顺序必须一致 [ { ( ) } ]
条件三指: 每个右括号都必须对应一个相同类型相同顺序的左括号, 且右括号必须在左括号的右侧

3> 题解

采取 栈 这种数据结构来解决该题, 比较容易
依次遍历string对象存储的字符串, 遇到左括号时, 将其存入栈对象,
遇到右括号, 弹出栈顶元素, 判断是否满足条件

思路一 – 依次遍历栈顶元素, 采取键值匹配的形式
#include<stack>
class Solution 
{
public:bool isValid(string s) {if(s.size() % 2)return false;stack<char> stk;int i = 0;char A;while(i<s.size()){switch(s[i]){case '(': stk.push(s[i]);          break;case '[':stk.push(s[i]);break;case '{':stk.push(s[i]);break;case ')':if(stk.empty())return false;A = stk.top();stk.pop();if(A != '(')return false;break;case ']':if(stk.empty())return false;A = stk.top();stk.pop();if(A != '[')return false;break;case '}':if(stk.empty())return false;A = stk.top();stk.pop();if(A != '{')return false;break;}++i;}return stk.empty();}
};
作者 : Joker不是Joker
时间复杂度 : O(n)
空间复杂度 : O(n)

225 . 用队列实现栈

1 . 题目介绍

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

实现 MyStack 类:

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

2 . 题目解析

注意 : 只可使用队列结构中的 push pop empty size front这几项接口来实现栈
使用先进先出的队列, 来实现后进先出的栈

3 . 题解

思路一 – 双队列实现栈

思路描述 : 每次进行插入后, 通过一个循环, 让队列前面的元素依次弹出队列并插入到队尾中 。 这样就使得插入到队尾的元素成功的跑到了队首的位置。

class MyStack {
public:queue<int> queue1;queue<int> queue2;MyStack() {}void push(int x) {if(queue1.empty()){queue1.push(x);return;}queue2.push(x);while(!queue1.empty()){int a = queue1.front();queue2.push(a);queue1.pop();}queue1 = queue2;while(!queue2.empty()){queue2.pop();}}int pop() {int a = queue1.front();queue1.pop();return a;}int top() {return queue1.front();}bool empty() {return queue1.empty();}
};
作者 : Joker不是Joker
时间复杂度 : O(n)
空间复杂度 : O(n)
思路二 – 单队列实现栈
class MyStack {
public:queue<int> queue1;MyStack() {}void push(int x) {if(queue1.size() == 0){queue1.push(x);}else{queue1.push(x);int num = 0;while(num < queue1.size()-1){int a = queue1.front();queue1.pop();queue1.push(a);++num;}cout << queue1.back() << " ";}}int pop() {int a = queue1.front();queue1.pop();return a;}int top() {return queue1.front();}bool empty() {return queue1.empty();}
};

232 . 用栈实现队列

1 . 题目介绍

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

实现 MyQueue 类:

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

2 . 本题要求

  • 你 只能 使用标准的栈操作 —— 也就是只有 push to top, peek/pop from top, size, 和 is empty 操作是合法的。
  • 你所使用的语言也许不支持栈。你可以使用 list 或者 deque(双端队列)来模拟一个栈,只要是标准的栈操作即可。

3 . 题解

思路一 – 单栈模拟队列的进或出
class MyQueue {
public:stack<int> stk1;stack<int> stk2;MyQueue() {}void push(int x) {while(!stk2.empty()){stk1.push(stk2.top());stk2.pop();}stk1.push(x);while(!stk1.empty()){stk2.push(stk1.top());stk1.pop();}}int pop() {int a = stk2.top();stk2.pop();return a;}int peek() {return stk2.top();}bool empty() {return stk2.empty();    }
};
作者 : Joker不是Joker
时间复杂度 : O(n)
空间复杂度 : O(1)
思路一 – 代码优化

代码优化了 每次进行插入都将来回颠倒stk1与stk2中的元素
改为了 如果只进行插入, 那么就会一直将元素插入至stk1中, 当进行删除时,再将stk1中的元素依次弹出且进入栈stk2 。
当 执行出栈后 ,在执行入栈, 会将stk2中的元素依次弹出且进入栈stk1中

lass MyQueue {
public:stack<int> stk1;stack<int> stk2;MyQueue() {}void push(int x) {if(stk2.empty()){stk1.push(x);}else{while(!stk2.empty()){stk1.push(stk2.top());stk2.pop();}stk1.push(x);}}int pop() {int a = 0;if(stk2.empty()){while(!stk1.empty()){stk2.push(stk1.top());stk1.pop();}a = stk2.top();stk2.pop();}else{a = stk2.top();stk2.pop();}return a;}int peek() {if(stk2.empty()){while(!stk1.empty()){stk2.push(stk1.top());stk1.pop();}}return stk2.top();}bool empty() {if(stk1.empty() && stk2.empty())return true;return false;}
};

622 . 设计循环队列

1 . 题目描述

设计你的循环队列实现。 循环队列是一种线性数据结构,其操作表现基于 FIFO(先进先出)原则并且队尾被连接在队首之后以形成一个循环。它也被称为“环形缓冲器”。
你的实现应该支持如下操作:

  • MyCircularQueue(k): 构造器,设置队列长度为 k 。
  • Front: 从队首获取元素。如果队列为空,返回 -1 。
  • Rear: 获取队尾元素。如果队列为空,返回 -1 。
  • enQueue(value): 向循环队列插入一个元素。如果成功插入则返回真。
  • deQueue(): 从循环队列中删除一个元素。如果成功删除则返回真。
  • isEmpty(): 检查循环队列是否为空。
  • isFull(): 检查循环队列是否已满。

循环队列的优势:

  • 循环队列的一个好处是我们可以利用这个队列之前用过的空间。在一个普通队列里,一旦一个队列满了,我们就不能插入下一个元素,即使在队列前面仍有空间。但是使用循环队列,我们能使用这些空间去存储新的值。

2 . 题目解析

实现一个循环队列, 意思是队头被删除的元素所占用的空间可以循环利用。
队列是一端进入, 另一端退出。
可以看为队尾进入, 队头退出。
当队头的元素被删除后, 其所在的队头变为队尾, 它的下一个元素变为队头。
这就需要两个指针, 一个头指针指向队头, 一个尾指针指向队尾。
两个指针在这个队列中不断循环移动, 因此实际意义上的队头和队尾是在不断变动的
由此可知, 应该通过顺序表来实现循环队列。

3 . 题解

思路一 – n+1个空间实现n个有效长度
typedef int QDataType;
class MyCircularQueue 
{
public:QDataType* arr;int head; int tail;int n;MyCircularQueue(int k) {arr = new QDataType[k+1];n=k+1;head = 0;tail = 0;}bool enQueue(int value) {if((tail-head+n)%n == (n-1))return false;if(tail == (n-1)){arr[tail] = value;tail = 0;}else{arr[tail] = value;++tail;}return true;}bool deQueue() {if(head == tail)return false;if(head == (n-1)){head = 0;}else{++head;}return true;}int Front() {if(head == tail)return -1;return arr[head];}int Rear() {if(head == tail)return -1;if(tail == 0)return arr[n-1];return arr[tail-1];}bool isEmpty() {return head == tail;}bool isFull() {return ((tail-head+n)%n == (n-1));}
};
作者 : Joker不是Joker
时间复杂度 : O(1)
空间复杂度 : O(n)

相关文章:

  • 中睿天下Coremail | 2023年Q3企业邮箱安全态势观察报告
  • rocketmq-exporter配置为系统服务-自启动
  • SQL对数据进行去重
  • Java自学第8课:电商项目(3) - 重新搭建环境
  • Linux实战一天一个小指令--《日志查看》
  • 设备报修流程要怎么优化?工单管理系统如何提高设备维修效率?
  • 云原生服务高可用性保持的简单思考
  • Linux 网络管理
  • 探秘美国服务器价格因素:成本、竞争力还是资源优势?
  • docker通过nginx代理tomcat-域名重定向
  • 使用JS 判断数组对象 里面的每一个字段,字段为空,就返回true, 所有字段不为空,返回 false
  • 【广州华锐互动】地震防灾减灾科普3D虚拟展厅:向公众普及地震安全知识
  • vue+react封装请求
  • 【Bug】当用opencv库的imread()函数读取图像,用matplotlib库的plt.imshow()函数显示图像时,图像色彩出现偏差问题的解决方法
  • JS 获取本周一,本周日,上周一,上周日,下周一,下周日,本月第一天,本月最后一天,上月第一天,上月最后一天,下月第一天,下月最后一天
  • es6--symbol
  • Java知识点总结(JavaIO-打印流)
  • js 实现textarea输入字数提示
  • k8s如何管理Pod
  • niucms就是以城市为分割单位,在上面 小区/乡村/同城论坛+58+团购
  • react-core-image-upload 一款轻量级图片上传裁剪插件
  • vue:响应原理
  • Webpack4 学习笔记 - 01:webpack的安装和简单配置
  • 浮现式设计
  • 吐槽Javascript系列二:数组中的splice和slice方法
  • 为物联网而生:高性能时间序列数据库HiTSDB商业化首发!
  • 消息队列系列二(IOT中消息队列的应用)
  • 做一名精致的JavaScripter 01:JavaScript简介
  • ​【原创】基于SSM的酒店预约管理系统(酒店管理系统毕业设计)
  • ​html.parser --- 简单的 HTML 和 XHTML 解析器​
  • $GOPATH/go.mod exists but should not goland
  • (2.2w字)前端单元测试之Jest详解篇
  • (C#)一个最简单的链表类
  • (SpringBoot)第二章:Spring创建和使用
  • (附源码)ssm本科教学合格评估管理系统 毕业设计 180916
  • (附源码)ssm码农论坛 毕业设计 231126
  • (万字长文)Spring的核心知识尽揽其中
  • (已解决)vue+element-ui实现个人中心,仿照原神
  • .NET 5.0正式发布,有什么功能特性(翻译)
  • .NET 中选择合适的文件打开模式(CreateNew, Create, Open, OpenOrCreate, Truncate, Append)
  • .net的socket示例
  • .net反混淆脱壳工具de4dot的使用
  • /etc/apt/sources.list 和 /etc/apt/sources.list.d
  • @Autowired标签与 @Resource标签 的区别
  • @ComponentScan比较
  • @requestBody写与不写的情况
  • [ Linux 长征路第五篇 ] make/Makefile Linux项目自动化创建工具
  • [ 环境搭建篇 ] 安装 java 环境并配置环境变量(附 JDK1.8 安装包)
  • [ 数据结构 - C++] AVL树原理及实现
  • [C#]无法获取源 https://api.nuge t.org/v3-index存储签名信息解决方法
  • [English]英语积累本
  • [Flex][问题笔记]TextArea滚动条问题
  • [GPT]Andrej Karpathy微软Build大会GPT演讲(上)--GPT如何训练
  • [POI2007] ZAP-Queries (莫比乌斯反演)
  • [Qualcomm][Power]QCM2290功耗异常问题