刷题笔记——栈和队列互相冒充

刷题笔记——栈和队列互相冒充

    • 5.3 用队列实现栈
      • 两队列实现栈
      • 一个队列实现栈
    • 5.4 用栈实现队列
      • 两栈实现队列
      • push栈和pop栈
      • 一个栈实现队列

5.3 用队列实现栈

原OJ题:225. 用队列实现栈 - 力扣(LeetCode)
请添加图片描述

两队列实现栈

  1. 入栈的实现

选非空的队列进行push,两个都空的话随便选。

  1. 出栈的实现和返回栈顶元素

假设我们有两个队列1、2。

若1队列非空,2队列为空,则1队列除了队尾全部转移到2队,1队仅剩的1个元素即为目标元素。

随着操作次数变多,我们可能会忘了哪个队列为空。此时需要假设一个队列为空,再去验证该队列是否为空。

  1. 判断队列是否为空

两个队列都没有数据时,栈才算为空。

为节省篇幅,这里用STL来模拟相应的数据结构。

参考程序:

#include<queue>
using namespace std;

class MyStack {
public:
    MyStack() {
        size=0;
    }
    
    void push(int x) {//入栈
        if(!q2.empty()){
            q2.push(x);
            size++;
        }
        else{
            q1.push(x);
            size++;
        }
    }
    
    int pop() {
        
        //假设队列q1为空
        queue<int>*emptyQ=&q1,*noEmptyQ=&q2;
        if(!(*emptyQ).empty()){
            emptyQ=&q2;
            noEmptyQ=&q1;
        }
        
        //将非空队列的数据转移到空队列
        while((*noEmptyQ).size()>1){
            (*emptyQ).push((*noEmptyQ).front());
            (*noEmptyQ).pop();
        }
        
        
        int t=(*noEmptyQ).front();//获取栈顶元素
        (*noEmptyQ).pop();
        size--;
        return t;
    }
    
    int top() {
        //这里的操作和pop函数是一样的
        queue<int>*emptyQ=&q1,*noEmptyQ=&q2;
        if(!(*emptyQ).empty()){
            emptyQ=&q2;
            noEmptyQ=&q1;
        }
        while((*noEmptyQ).size()>1){
            (*emptyQ).push((*noEmptyQ).front());
            (*noEmptyQ).pop();
        }
        int t=(*noEmptyQ).front();
        (*noEmptyQ).pop();
        
        (*emptyQ).push(t);
        return t;
    }
    
    bool empty() {
        return size==0;
    }
private:
    queue<int>q1,q2;
    int size;
};

/**
 * 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();
 */

一个队列实现栈

假设我们只有一个队列q。

思路:

  1. 入栈

假设我们要将数据x入队。

若队列q为空,则x正常入队。

若队列有数据,则先标记队列内的元素长度,再将x入队,最后将除了x的数据全部进行先出队再入队的操作,保证队首始终为后进的元素。

  1. 出栈和获取栈顶元素

队列正常弹出队首即可。

  1. 判断栈是否为空

直接判断队列是否为空即可。

参考程序:

#include<queue>
using std::queue;

class MyStack {
public:
    void push(int x) {
        int num=q.size();//获取当前队列元素个数
        q.push(x);
        while(num--){//除了x都进行一次排队的操作
            int t=q.front();
            q.pop();
            q.push(t);
        }
    }
    
    //之后都是正常队列的操作
    int pop() {
        int t=q.front();
        q.pop();
        return t;
    }
    
    int top() {
        int t=q.front();
        return t;
    }
    
    bool empty() {
        return q.empty();
    }
private:
    queue<int>q;
};

/**
 * 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();
 */

5.4 用栈实现队列

232. 用栈实现队列 - 力扣(LeetCode)
请添加图片描述

两栈实现队列

模仿两队列实现栈的思路。

参考程序:

#include<stack>
using std::stack;

class MyQueue {
public:
    MyQueue() {
        size=0;
    }
    
    void push(int x) {
        if(!s2.empty()){
            s2.push(x);
            size++;
        }
        else{
            s1.push(x);
            size++;
        }
    }
    
    int pop() {
        //找出空栈
        stack<int>*emptyS=&s1,*noEmptyS=&s2;
        if(!(*emptyS).empty()){
            emptyS=&s2;
            noEmptyS=&s1;
        }
        
        //获取栈顶元素
        while((*noEmptyS).size()>1){
            (*emptyS).push((*noEmptyS).top());
            (*noEmptyS).pop();
        }
        int t=(*noEmptyS).top();
        (*noEmptyS).pop();//这步使非空栈变为空
        size--;

        return t;
    }
    
    int peek() {
        stack<int>*emptyS=&s1,*noEmptyS=&s2;
        if(!(*emptyS).empty()){
            emptyS=&s2;
            noEmptyS=&s1;
        }
        while((*noEmptyS).size()>1){
            (*emptyS).push((*noEmptyS).top());
            (*noEmptyS).pop();
        }
        int t=(*noEmptyS).top();
        
        while((*emptyS).size()){//因为没有进行pop操作,需要将数据放回原栈
            
            (*noEmptyS).push((*emptyS).top());
            (*emptyS).pop();
        }

        return t;
    }
    

    bool empty() {
        return size==0;
    }
private:
    stack<int>s1,s2;
    int size;
};

/**
 * Your MyCircularQueue object will be instantiated and called as such:
 * MyCircularQueue* obj = new MyCircularQueue(k);
 * bool param_1 = obj->enQueue(value);
 * bool param_2 = obj->deQueue();
 * int param_3 = obj->Front();
 * int param_4 = obj->Rear();
 * bool param_5 = obj->isEmpty();
 * bool param_6 = obj->isFull();
 */

push栈和pop栈

  1. 入队

一个栈用于实现数据入队操作,记为ins栈;另一个栈用于实现出队操作,记为outs栈。

  1. 出队

outs栈为空,则ins栈的数据全部压入outs栈再pop;

outs栈非空,直接出栈即可。

  1. 获取队首元素

套用出栈的思路即可。

或将出栈获取栈顶元素的步骤用于获取栈顶元素的函数的实现,出栈的函数调用获取栈顶元素的函数即可。

  1. 判断队列是否为空

两个栈都为空,队列则为空。

参考程序:

class MyQueue {//一个栈用于push,一个栈用于pop
public:
    MyQueue() {
        size=0;
    }
    
    void push(int x) {//入栈
        ins.push(x);
        size++;
    }
    
    int pop() {//出栈
        int t=this->peek();
        outs.pop();
        size--;
        return t;
    }
    
    int peek() {//获取栈顶元素
        if(outs.empty()){
            while(ins.size()>1){
                outs.push(ins.top());
                ins.pop();
            }
            int t=ins.top();
            ins.pop();
            outs.push(t);//到这里,ins栈为空
            return t;
        }
        return outs.top();
    }
    

    bool empty() {
        return size==0;
    }
private:
    stack<int>ins,outs;
    int size;
};

一个栈实现队列

原则上一个栈是不可能实现完整的队列操作,至少需要两个栈。

但我们可以利用栈的特性,通过递归来暂时替代另一个栈的功能。

  1. 入队

假设元素x为入队的元素。

若栈内没有元素,则x直接入栈。

若栈内有元素,则先取出栈顶元素进行保存,之后进行递归。直到栈空时,将x入栈。之后回溯的过程中将通过递归保存的数据重新放回栈。

  1. 出队

正常弹出栈顶元素即可。

  1. 获取队首元素

正常返回栈顶元素即可。

  1. 判断队列是否为空

栈为空,队列则为空。

这里入队的每层递归时间复杂度都为 O ( 1 ) O(1) O(1),所有的 n n n个数据都进行一次递归的话,时间复杂度为 O ( n ) O(n) O(n)

参考程序:

#include<stack>
using std::stack;

class MyQueue {
public:
    void push(int x) {
        //栈为空则x入栈
        if(sk.empty()){
            sk.push(x);
            return;
        }
        int t=sk.top();
        sk.pop();
        push(x);
        sk.push(t);//回溯操作其实也用到了系统自带的栈
        
    }
    
    int pop() {
        int t=sk.top();
        sk.pop();
        return t;
    }
    
    int peek() {
        int t=sk.top();
        return t;
    }
    

    bool empty() {
        return sk.empty();
    }
private:
    stack<int>sk;
};

/**
 * 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();
 */

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Mysql基础 01 数据与sql

文章目录 一、基本概念二、mysql的常用命令三、sql规范四、数据类型五、SQL语句 一、基本概念 数据库(database,DB)&#xff1a;存储数据的仓库。 数据库管理系统软件(Database Management System,DBMS)&#xff1a;是一种操作和管理数据库的大型软件。常见的DBMS有oracle、s…

5G NR:各物理信道的DMRS配置

DMRS简介 在5G中&#xff0c;DMRS&#xff08;DeModulation Reference Signal&#xff09;广泛存在于各个重要的物理信道当中&#xff0c;如下行的PBCH&#xff0c;PDCCH和PDSCH&#xff0c;以及上行的PUCCH和PUSCH。其最为重要的作用就是相干解调&#xff08;Coherence Demodu…

从零开始:利用Portainer CE和cpolar搭建NextCloud私有云存储

文章目录 前言1. 在PortainerCE中创建NextCloud容器2. 公网远程访问本地NextCloud容器2.1 内网穿透工具安装3.2 创建远程连接公网地址 3. 固定NextCloud私有云盘公网地址 前言 本文将介绍如何在本地利用Portainer CE的可视化界面创建NextCloud私有云盘容器&#xff0c;并通过c…

第三十七章 Vue之编程式导航及跳转传参

目录 一、编程式导航跳转方式 1.1. path 路径跳转 1.1.1. 使用方式 1.1.2. 完整代码 1.1.2.1. main.js 1.1.2.2. App.vue 1.1.2.3. index.js 1.1.2.4. Home.vue 1.1.2.5. Search.vue 1.2. name 命名路由跳转 1.2.1. 使用方式 1.2.2. 完整代码 1.2.2.1. main.js 1…

人工智能(AI)和机器学习(ML)技术学习流程

目录 人工智能(AI)和机器学习(ML)技术 自然语言处理(NLP): Word2Vec: Seq2Seq(Sequence-to-Sequence): Transformer: 范式、架构和自注意力: 多头注意力: 预训练、微调、提示工程和模型压缩: 上下文学习、思维链、全量微调、量化、剪枝: 思维树、思维…

升级改进策略:鸡只图像分割

鸡只图像分割系统源码&#xff06;数据集分享 [yolov8-seg-rtdetr&#xff06;yolov8-seg-p2等50全套改进创新点发刊_一键训练教程_Web前端展示] 1.研究背景与意义 项目参考ILSVRC ImageNet Large Scale Visual Recognition Challenge 项目来源AAAI Global Al lnnovation C…

1.62亿元!812个项目立项!上海市2024年度“科技创新行动计划”自然科学基金项目立项

本期精选SCI&EI ●IEEE 1区TOP 计算机类&#xff08;含CCF&#xff09;&#xff1b; ●EI快刊&#xff1a;最快1周录用&#xff01; 知网(CNKI)、谷歌学术期刊 ●7天录用-检索&#xff08;100%录用&#xff09;&#xff0c;1周上线&#xff1b; 免费稿件评估 免费匹配期…

软件设计师下午题UML15分

一、涉及到的图及对应关系 二、例题 1.用例图和类图的例题 解析及答案 2.状态图和类图的例题 3.通信图和类图例题 例题

如何找到养生生活视频素材?推荐几个优秀网站

今天&#xff0c;我们来聊一个实用的话题&#xff0c;那就是如何找到优质的养生视频素材。作为自媒体创作者&#xff0c;高质量的视频素材对内容制作至关重要。不论你是刚入行的新手&#xff0c;还是已经积累了一定粉丝的大V&#xff0c;找到合适的养生视频素材都能帮助你更好地…

书生大模型第四期闯关任务与笔记

书生大模型第四期闯关任务与笔记 入门岛第一关 Linux闯关任务&#xff1a;完成SSH连接与端口映射并运行hello_world.py笔记与过程SSH端口映射linux文件管理命令linux进程管理命令 第二关 Python闯关任务&#xff1a;Leetcode 383(笔记中提交代码与leetcode提交通过截图)闯关任务…

Zabbix 7 最新版本安装 Rocky Linux 8

前言 本实验主要在Rocky Linux 中安装Zabbix&#xff0c;其他centos8、Debian、Ubuntu、Alma Linux都可以安装&#xff0c;就是在中间件有点不同。Nginx就要配置一下&#xff0c;官网给的教程也算是很规范的&#xff0c;就是在MySQL上要自己安装&#xff0c;他没有告诉我们&am…

Odoo:免费开源的钢铁冶金行业ERP管理系统

文 / 开源智造 Odoo亚太金牌服务 简介 Odoo免费开源ERP集成计质量设备大宗原料采购&#xff0c;备件设材全生命周期&#xff0c;多业务模式货控销售&#xff0c;全要素追溯单品&#xff0c;无人值守计量物流&#xff0c;大宗贸易交易和精细化成本管理等方案&#xff1b;覆盖…

刷题强训(day05) -- 游游的you、腐烂的苹果、孩子们的游戏(圆圈中最后剩下的数)

目录 1、游游的you 1.1 题目 1.2 思路 1.3 代码实现 2、腐烂的苹果 2.1 题目 2.2 思路 2.3 代码实现 3、孩子们的游戏(圆圈中最后剩下的数) 3.1 题目 3.2 思路 3.3 代码实现 3.3.1 环形链表 ​编辑3.3.2 动态规划 ​编辑 1、游游的you 1.1 题目 1.2 思路 根据题…

Java | Leetcode Java题解之第546题移除盒子

题目&#xff1a; 题解&#xff1a; class Solution {int[][][] dp;public int removeBoxes(int[] boxes) {int length boxes.length;dp new int[length][length][length];return calculatePoints(boxes, 0, length - 1, 0);}public int calculatePoints(int[] boxes, int l…

精华帖分享|历史波动率和已实现波动率纠缠研究

本文来源于量化小论坛公共讨论区板块精华帖&#xff0c;作者为期权罗&#xff0c;发布于2023年11月24日。 以下为精华帖正文&#xff1a; 01 思路由来 波动率研究有很多学术化得研究成果&#xff0c;比较枯燥/难&#xff0c;最近结合波动率继续交易了段时间&#xff0c;一是开…

ssm088基于JAVA的汽车售票网站abo+vue(论文+源码)_kaic

毕 业 设 计&#xff08;论 文&#xff09; 题目&#xff1a;汽车售票网站的设计与实现 摘 要 互联网发展至今&#xff0c;无论是其理论还是技术都已经成熟&#xff0c;而且它广泛参与在社会中的方方面面。它让信息都可以通过网络传播&#xff0c;搭配信息管理工具可以很好地为…

LeetCode Hot100 49.字母异位词分组

题干&#xff1a; 思路&#xff1a; 输入的是一个字符串数组&#xff0c;输出是一个列表&#xff0c;首先我们需要通过遍历数组获得每一个字符串&#xff0c;我们想要判断获得的任意两个字符串是不是字母异位词&#xff0c;所以可以将获得的字符串排序&#xff08;转换为字符数…

金属箔电阻

6.金属箔电阻如何实现“高精度” 电阻的阻值会受到各种“应力”影响而发生改变&#xff0c;离开稳定性的高精度是没有意义的。 例如&#xff0c;电阻出厂时的精度时0.01%&#xff0c;为了实现精度付出了高昂的费用&#xff0c;但在几个月的存储或几百个小时的负载后阻值的变化…

地下水数值模拟、 地下水环评、Visual modflow Flex、Modflow

地下水数值模拟软件Visual modflow Flex实践技术应用 地下水数值模拟软件的应用&#xff0c;主要围绕的目前应用较为广泛的Visual Modflow Flex 6.1软件版本开展&#xff0c;结合具体应用场景&#xff0c;实例讲解软件的全流程应用过程&#xff0c;包括数据处理分析、数值模型…

Python 爬虫运行状态监控:进度、错误与完成情况

Python 爬虫运行状态监控&#xff1a;进度、错误与完成情况 在进行大规模数据爬取时&#xff0c;监控爬虫的运行状态至关重要。通过实时监控&#xff0c;可以了解爬虫的工作进度、出现的错误以及任务完成情况。这样可以及时发现并解决问题&#xff0c;确保数据抓取任务顺利进行…