力扣(leetcode)经典题目分享第3期——栈和队列

news2025/1/16 5:30:09

栈和队列

  • 一. 选择题
    • 1.1 进出栈顺序
    • 1.2 循环队列
    • 1.3 队列的基本运算
    • 1.4 循环队列的有效长度
  • 二. OJ练习题
    • 2.1 括号匹配问题
    • 2.2 用队列实现栈
    • 2.3 用栈实现队列
    • 2.4 循环队列
  • 总结:

一. 选择题

1.1 进出栈顺序

若进栈序列为 1,2,3,4 ,进栈过程中可以出栈,则下列不可能的一个出栈序列是()
A 1,4,3,2
B 2,3,4,1
C 3,1,4,2
D 3,4,2,1

答案:C
解析:出栈的要求是先出栈顶元素。C选项是先出的3,那么此时栈中还有1和2,如果第二个要出栈的话,只能出栈顶的2,而他出的1,所以C选项肯定是错的。

1.2 循环队列

循环队列的存储空间为 Q(1:100) ,初始状态为 front=rear=100 。经过一系列正常的入队与退队操作
后, front=rear=99 ,则循环队列中的元素个数为( )
A 1
B 2
C 99
D 0或者100
答案:D
解析:由于循环队列的性质,当front==rear时,不能判断队列为空还是为满,所以D正确。

1.3 队列的基本运算

4.以下( )不是队列的基本运算?
A 从队尾插入一个新元素
B 从队列中删除第i个元素
C 判断一个队列是否为空
D 读取队头元素的值
答案:B

1.4 循环队列的有效长度

5.现有一循环队列,其队头指针为front,队尾指针为rear;循环队列长度为N。其队内有效长度为?(假设
队头不存放数据)
A (rear - front + N) % N + 1
B (rear - front + N) % N
C ear - front) % (N + 1)
D (rear - front + N) % (N - 1)
答案:B

二. OJ练习题

需要注意的点:本篇博客的代码中用到的数据结构可以从我上一期博客中找到。链接。

2.1 括号匹配问题

题目介绍:
给定一个只包括 ‘(’,‘)’,‘{’,‘}’,‘[’,‘]’ 的字符串 s ,判断字符串是否有效。
有效字符串需满足:左括号必须用相同类型的右括号闭合。左括号必须以正确的顺序闭合。每个右括号都有一个对应的相同类型的左括号。

OJ链接
思路分析:
使用一个栈来存储字符串中的左括号,如果遇到字符串中的右括号,则出栈匹配,一旦匹配失败则返回false,否则就一直匹配,直到将数组元素全部匹配完成,返回true。
代码实现:

bool isValid(char * s)
{
    Stack st;
    StackInit(&st);
    while(*s)
    {
        if((*s=='(')||(*s=='[')||(*s=='{'))
        {
            StackPush(&st,*s);
            s++;
        }
        else
        {
            if(StackEmpty(&st)==true)//数组只有有括号时的处理
                      return false;
            STDataType tmp=StackTop(&st);
            StackPop(&st);
            if((*s==')'&&tmp!='(')
                  ||(*s==']'&&tmp!='[')
                      ||(*s=='}'&&tmp!='{'))
                      return false;
            else
            {
                s++;
            }
        }
    }
    bool ret=StackEmpty(&st);//数组只有左括号时的处理
    StackDestroy(&st);
    return ret;
}

2.2 用队列实现栈

题目介绍:请你仅使用两个队列实现一个后入先出(LIFO)的栈,并支持普通栈的全部四种操作(push、top、pop 和 empty)。 OJ链接。
思路分析:队列先进先出,栈是后进先出。主要解决出栈时的问题,本题需要使用两个队列才能实现栈,当出栈时,将一个队列中的元素转移到另一个空队列中,原队列只保留队尾元素,此时该元素就是我们要出栈的元素。之后每次出栈都以同样的方法倒元素即可。
图解:
在这里插入图片描述
此时需要出栈顶元素5,我们将队列1的元素倒到队列2去,其中队列1只留一个元素
在这里插入图片描述
这时队列1就只剩5这个元素了,对其操作即可。
代码如下:

typedef struct {
    Queue q1;
    Queue q2;
} MyStack;


MyStack* myStackCreate() 
{
    MyStack* st=(MyStack*)malloc(sizeof(MyStack));
    QueueInit(&st->q1);
    QueueInit(&st->q2);
    return st;
}

void myStackPush(MyStack* obj, int x) 
{
    if(QueueEmpty(&obj->q2))
    {
        QueuePush(&obj->q1,x);
    }
    else
    {
        QueuePush(&obj->q1,x);
    }
}

int myStackPop(MyStack* obj) 
{
    if(!QueueEmpty(&obj->q1))
    {
        while(QueueSize(&obj->q1)>1)
        {
            QueuePush(&obj->q2,QueueFront(&obj->q1));
            QueuePop(&obj->q1);
        }
        int tmp=QueueFront(&obj->q1);
        QueuePop(&obj->q1);
        return tmp;
    }
    else
    {
        while(QueueSize(&obj->q2)>1)
        {
            QueuePush(&obj->q1,QueueFront(&obj->q2));
            QueuePop(&obj->q2);
        }
        int tmp=QueueFront(&obj->q2);
        QueuePop(&obj->q2);
        return tmp;
    }
}

int myStackTop(MyStack* obj) 
{
    if(!QueueEmpty(&obj->q1))
    {
        return QueueBack(&obj->q1);
    }
    else
    {
        return QueueBack(&obj->q2);
    }
}

bool myStackEmpty(MyStack* obj) 
{
    return (QueueEmpty(&obj->q1)&&QueueEmpty(&obj->q2));
}

void myStackFree(MyStack* obj)
{
    QueueDestroy(&obj->q1);
    QueueDestroy(&obj->q2);
    free(obj);
}

2.3 用栈实现队列

题目介绍:请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(push、pop、peek、empty)。OJ链接。
思路分析:同样是使用两个栈来实现队列,需要注意队列是先进先出,其中一个栈用来入队(pushst),一个栈专门用来出队(popst)。当出队时,如果popst为空,就将pushst中的元素倒到popst中,再在popst里出栈。

代码如下:

typedef struct 
{
    Stack popst;
    Stack pushst;
} MyQueue;


MyQueue* myQueueCreate()
{
    MyQueue* tmp=(MyQueue*)malloc(sizeof(MyQueue));
    StackInit(&tmp->popst);
    StackInit(&tmp->pushst);
    return tmp;
}

void myQueuePush(MyQueue* obj, int x)
{
    StackPush(&obj->pushst,x);
}

int myQueuePeek(MyQueue* obj)
{
    if(StackEmpty(&obj->popst))
    {
        while(StackSize(&obj->pushst)>0)
        {
            StackPush(&obj->popst,StackTop(&obj->pushst));
            StackPop(&obj->pushst);
        }
        return StackTop(&obj->popst);
    }
    return StackTop(&obj->popst);
}
int myQueuePop(MyQueue* obj) 
{
    int top=myQueuePeek(obj);
    StackPop(&obj->popst);
    return top;
}


bool myQueueEmpty(MyQueue* obj) 
{
    return StackEmpty(&obj->popst)&&StackEmpty(&obj->pushst);
}

void myQueueFree(MyQueue* obj) 
{
    StackDestroy(&obj->popst);
    StackDestroy(&obj->pushst);
    free(obj);
}

2.4 循环队列

题目介绍:
设计你的循环队列实现。 循环队列是一种线性数据结构,其操作表现基于 FIFO(先进先出)原则并且队尾被连接在队首之后以形成一个循环。它也被称为“环形缓冲器”。
循环队列的一个好处是我们可以利用这个队列之前用过的空间。在一个普通队列里,一旦一个队列满了,我们就不能插入下一个元素,即使在队列前面仍有空间。但是使用循环队列,我们能使用这些空间去存储新的值。
在这里插入图片描述
OJ链接
思路分析:
这里我们并不是使用链表来实现循环队列,而是使用数组来实现它。原因是因为单链表实现循环列表的话,不好处理队尾元素。所以我们就使用数组来实现循环队列。该部分较难,我将一些需要注意的地方写了出来,大家自己写的时候应该加以注意,后面也会有代码可以对照。
需要注意的是:
假设队头尾front,队尾为rear,队列容量为k,那么:

  1. 开空间时,需要多开一个,以解决判空和判满问题。
  2. 判断队列是否满了:(rear+1)%(k+1)==front
  3. 每次push后,rear需要%=k+1
  4. 每次pop后,front需要%=k+1
    代码如下:
typedef struct 
{
    int* a;
    int head;
    int tail;
    int k;
} MyCircularQueue;


MyCircularQueue* myCircularQueueCreate(int k) 
{
    MyCircularQueue* obj=(MyCircularQueue*)malloc(sizeof(MyCircularQueue));
    obj->a=(int*)malloc(sizeof(int)*(k+1));
    obj->head=obj->tail=0;
    obj->k=k;
    return obj;
}
bool myCircularQueueIsEmpty(MyCircularQueue* obj) 
{
    assert(obj);
    return obj->head==obj->tail;
}

bool myCircularQueueIsFull(MyCircularQueue* obj) 
{
    assert(obj);  
    int tail= (obj->tail+1)%(obj->k+1);
    return tail==obj->head;
}
bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) 
{
    assert(obj);
    if(myCircularQueueIsFull(obj))
    {
        return false;
    }
    obj->a[obj->tail]=value;
    obj->tail++;
    obj->tail %= (obj->k + 1);
    return true;
}

bool myCircularQueueDeQueue(MyCircularQueue* obj) 
{
    assert(obj);
    if(myCircularQueueIsEmpty(obj))
    {
        return false;
    }
    obj->head++;
    obj->head%=(obj->k+1);
    return true;
}

int myCircularQueueFront(MyCircularQueue* obj) 
{
    assert(obj);
    if(myCircularQueueIsEmpty(obj))
    {
        return -1;
    }
    return obj->a[obj->head];
}

int myCircularQueueRear(MyCircularQueue* obj) 
{
    if(myCircularQueueIsEmpty(obj))
    {
        return -1;
    }
    int tail=obj->tail==0?obj->k:obj->tail-1;
    return obj->a[tail];
}



void myCircularQueueFree(MyCircularQueue* obj) 
{
    assert(obj);
    free(obj->a);
    free(obj);
}

总结:

本篇博客主要介绍了一些常见的选择题和OJ题,主要考察的还是队列和栈的性质。关于循环队列的部分呢,难度较大,没有特殊要求的话,可以跳过。

在这里插入图片描述

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

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

相关文章

unreal编译源码搭建dedicated server的流水账——但是细

参考视频: B站的视频: https://www.bilibili.com/video/BV1wk4y1m7wz/?spm_id_from333.337.search-card.all.click&vd_sourced33b44674c517c8b7928e8d3ac316b37 YouTube的视频: https://www.youtube.com/watch?vAKiGajA7AXM 和上面的视…

基于STM32CUBEMX驱动多个VL6180X

概述 VL6180X是基于ST FlightSense™专利技术的最新产品。这是一个突破性的技术,实现了独立于目标反射率的绝对距离测量。现有技术通过测量反射光的光量来估算距离,这种方法的最大缺点是被测物体的颜色和表面对测量精度影响很大,而VL6180X则…

云端办公后,协同软件也能轻松做好项目管理

最近很多朋友在后台问我,数字化移动办公环境下如何做好项目管理,但是问题不够聚焦,所以我决定从自己的理解出发,分享一下项目管理的一些心得。需要说明的是,传统项目管理和互联网项目管理存在很大的差异,尤…

MyBatis源码(二)如何执行sql

前言 接着environmentElement获取数据源信息后,同级执行代码的mappersElement。 Mybatis源码(三)如何操作数据库 MyBatis源码(二)如何执行sql Mybatis源码(一)获取数据源 结构小结 分析ma…

Leetcode 2. 两数相加(高精度加法模板)

Leetcode 2. 两数相加 题目 思路 链表从头开始存放数据的个位十位 百位新建一个链表C,将链表A和B每一个相加的结果存放在C中,注意加法的进位 代码 /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode n…

实力领航|万应智谷云平台成功入选2022中国互联网大会“互联网助力经济社会数字化转型”特色案例

近日,以“发展数字经济 促进数字文明”为主题,由工业和信息化部、深圳市人民政府主办,中国互联网协会、广东省通信管理局、深圳市工业和信息化局等单位承办的2022(第二十一届)中国互联网大会在深圳国际会展中心召开。开…

【超多代码、超多图解】Node.js一文全解析

目录一、Node.js简介1.1什么是Node.js1.2 Node.js可以做什么1.3 Node.js的安装1.4 Node.js的使用二、模块化处理2.1 什么是模块化2.2 内置模块2.2.1 fs文件系统模块(1)基本用法(2)防止动态拼接(3)路径问题2.2.2 path内置模块2.2.3…

前缀函数与KMP算法

一,前缀函数 1,定义 该函数存储一个字符串的各个长度的子串真前缀与真后缀相等的长度(注意,真前缀最多长度为n-1,不包含最后一个字符,真后缀同理,不包含第一个字符) 用p[i]数组储…

【LeetCode每日一题】——744.寻找比目标字母大的最小字母

文章目录一【题目类别】二【题目难度】三【题目编号】四【题目描述】五【题目示例】六【解题思路】七【题目提示】八【时间频度】九【代码实现】十【提交结果】一【题目类别】 二分查找 二【题目难度】 简单 三【题目编号】 744.寻找比目标字母大的最小字母 四【题目描述…

【小5聊】基础算法 - 实现字符串1到N位长度的组合关键词

在本篇文章中,我们讲一起了解下基础算法的运用 在程序开发里,算法无处不在,掌握算法才能更好的提高程序效率和质量 【算法返回效果】 【实现的功能描述】 当前算法主要实现输入一定长度的字符串后,能够返回按顺序1个字符长度、…

第二证券|七位投资专家指点2023 战略性看好A股 市场将提供更多机会

2022年行将收官,2023年新征途行将开启。 阅历了本年的一波三折、震动大跌,2023年A股商场将怎么演绎?有哪些时机值得注重?哪些危险要素需求留意? 对此,我国基金报记者专访了来自公募、券商资管、私募的七位…

Vjudge如何绑定洛谷账号

因为洛谷不支持Vjudge的bot提交,一个学弟问我才发现。要绑定洛谷账号才能在vj本地提交,绑定的方法也很奇怪,方法如下。 在题目来自洛谷的题目界面点击提交,出现如下界面。 发现没有bot提交选项,只能选择My Account,点…

NetInside网络攻击分析帮您轻松发现网络异常

分析概述 分析概述从以下四点做介绍。 故障信息来源 根据网络管理老师提供信息,29日上午7点半到9点时分,网络出现过故障。 分析对象 使用NetInside全流量分析系统对改故障进行分析。 分析思路 1、对比分析故障时段与非故障时段总流量信息。 2、对…

硬盘数据恢复的方法有哪些?这五种恢复方法你知道吗

硬盘通常泛指电脑硬盘,也可以将其定义为电脑数据的“载体”。硬盘的主要作用是存储数据,它具有读写速度快、耗能低、体积小等优势,但是在使用过程中,总会遇到硬盘数据丢失问题,比如受病毒感染、误格式化、误删除、操作…

C++中的多态(概念篇)

多态的概念 通俗来说,就是多种形态,具体点就是去完成某一个行为,不同的对象去完成时会产生出不同的状态。比如最常见的买票,学生为半价,成人为全票。 多态的分类 静态的多态:如函数重载,看起…

【Linux入门指北】 网站服务

网站服务 文章目录网站服务一、简介二、静态站点三、动态站点1.LAMP2.部署论坛系统discuz3.部署博客系统 wordpress4.部署网上商城 ecshop5.部署网校系统edusoho一、简介 1.前言 UI的转变:B/S架构 2.名词 HTML( HyperText Markup Language)…

Arduino 简易屏显电子温度计

Arduino 简易屏显电子温度计一、前言二、硬件要求三、参数基础四、原理剖析五、实验思路六、程序概要七、arduino使用接线八、成果展示九、总结一、前言 温度计的使用,在日常生活中随处可见,电子行业也有相应的温控传感器设备,不管的是电子芯…

单片机实训day6——Proteus8.6版本+ STM32F103驱动LCD12864显示Keil5程序设计

内 容:实现LCD显示 学 时:4学时 知识点:LCD12864芯片介绍,读写操作时序,电路设计 重点: 读写操作时序 难点:读写操作时序 时间:2022年12月26日 9:00~11:50 总结&…

抖音小程序实践一:申请初始化

一、官方文档与实践 抖音小程序是什么?从官方视频了解 从2022年开始,字节跳动就开始火力全开的与知名企业合作,推动抖音小程序的孵化,然后逐步开放普通企业争相进入抖音小程序领域,来分一分流量的红利。 巨量星图抖…

微信小程序----使用发布订阅模式

目录 前言 小程序使用PubSubJS 获取 PubSubJS npm 构建 使用pubsub-js 1、使用publish发布消息 2、使用subscribe函数订阅消息 前言 发布-订阅模式 又叫 观察者模式。 它定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于…