关于栈和队列的几个题

news2024/11/24 12:08:15

思维导图:

 

 

1.匹配括号

题目如下:

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

有效字符串需满足:

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

题目链接:https://leetcode.cn/problems/valid-parentheses/ 

接口:

bool isValid(char * s){

}

分析:

 根据题目的意思,当相邻最近的左括号与右括号匹配到一块才能被叫做有效的括号。当左右括号不匹配时就要返回false。根据栈的后进先出的特点,我们可以将左括号入栈,然后在遇到右括号时就出一个左括号来与右括号匹配。这样一定可以实现相邻最近的两个左右括号的匹配。

代码:

 1.首先要建立一个栈

 typedef char DataType;
typedef struct ST
{
	DataType* a;//数组指针
	int Top;//栈顶指针
	int capaCity;//容量
}ST;
void STinit(ST* stack)
{
	assert(stack);
	assert(stack->a);
	stack->a = NULL;
	stack->Top = 0;
	stack->capaCity = 0;
}

void STpush(ST* stack,int x)
{
	assert(stack);
	if (stack->capaCity == stack->Top)//扩容操作
	{
		int newCapacity = stack->capaCity == 0 ? 4 : 2 * stack->capaCity;
		stack->a = (DataType*)realloc(stack->a, newCapacity * sizeof(DataType));
		if (stack->a == NULL)
		{
			perror("realloc fail");
			return ;
		}
		stack->capaCity = newCapacity;
	}
		stack->a[stack->Top] = x;
		stack->Top++;
}
bool STEmpty(ST* stack)
{
	assert(stack);
	return stack->Top == 0;
}
void STPop(ST* stack)
{
	assert(stack);
	assert(!STEmpty(stack));
	stack->Top--;
}
DataType STFront(ST* stack)
{
	assert(stack);
	assert(stack->a);
	DataType* front = stack->a[stack->Top - 1];
	return front;
}
void STDestory(ST* stack)
{
	assert(stack);
	free(stack->a);
	stack->Top = stack->capaCity = 0;
}

 2.写匹配代码

括号的匹配的代码的思路是左括号入栈。当遇到右括号时就出栈顶的左括号与右括号进行过匹配。匹配时分三种情况:

1.当不匹配时直接返回false

2.当先出现右括号时直接不匹配

3.当遍历完字符串以后栈内还有左括号,那左括号与右括号的数量关系就是不对等的,返回false.

bool isValid(char * s){
    ST stack;
    STinit(&stack);
while(*s)
{
    if(*s == '('||*s=='{'||*s=='[')
    {
        STpush(&stack,*s);//当*s为左括号时就入栈
    }
    else
    {   //当遇到右括号时比较,比较分三种情况
        if(STEmpty(&stack))//当右括号先出现时一定匹配不成功
        {
           STDestory(&stack);
           return false;
        }
      char Top = STTop(&stack);
      STPop(&stack);
      if(*s==']')
      {
          if(Top=='{'||Top=='(')
          {
               STDestory(&stack);
              return false;
          }
      }
       if(*s=='}')
      {
          if(Top=='('||Top=='(')
          {
               STDestory(&stack);
              return false;
          }
      }
       if(*s==')')
      {
          if(Top=='{'||Top=='[')
          {
               STDestory(&stack);
              return false;
          }
      }
    }
    s++;
}
if(!STEmpty(&stack))//当栈内的左括号还没有出完,那左右括号的数量就不是相同的
{
    STDestory(&stack);
    return false;
}
return true;
}

2,用栈实现队列

题目:

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

实现 MyQueue 类:

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

题目链接:https://leetcode.cn/problems/implement-queue-using-stacks/

题目接口:

typedef struct {

} MyQueue;


MyQueue* myQueueCreate() {

}

void myQueuePush(MyQueue* obj, int x) {

}

int myQueuePop(MyQueue* obj) {

}

int myQueuePeek(MyQueue* obj) {

}

bool myQueueEmpty(MyQueue* obj) {

}

void myQueueFree(MyQueue* obj) {

}

分析:

先想想栈与队列的差别:栈是后进先出的,队列是先进先出的。我们该如何改变栈的后进先出的顺序将其改成先进先进先出呢?答案是通过两个栈来交换:

我们该如何来利用两个Stack来改变顺序呢?答案就是将Stack1中的数据从栈顶按顺序导入到Stack2中,这样栈顶元素就变成了栈底元素了。

显然当我们要出数据时只要出Stack2中的数据便可以了。所以又可以将Stack2改名叫PopStack,Stack1改名叫做PushStack.根据以上逻辑写出代码如下:

先创建栈:

typedef int DataType;
typedef struct ST
{
	DataType* a;//数组指针
	int Top;//栈顶指针
	int capaCity;//容量
}ST;

void STinit(ST* stack)
{
	assert(stack);
	assert(stack->a);
	stack->a = NULL;
	stack->Top = 0;
	stack->capaCity = 0;
}

void STpush(ST* stack,int x)
{
	assert(stack);
	if (stack->capaCity == stack->Top)//扩容操作
	{
		int newCapacity = stack->capaCity == 0 ? 4 : 2 * stack->capaCity;
		stack->a = (DataType*)realloc(stack->a, newCapacity * sizeof(DataType));
		if (stack->a == NULL)
		{
			perror("realloc fail");
			return ;
		}
		stack->capaCity = newCapacity;
	}
		stack->a[stack->Top] = x;
		stack->Top++;
}
bool STEmpty(ST* stack)
{
	assert(stack);
	return stack->Top == 0;
}
void STPop(ST* stack)
{
	assert(stack);
	assert(!STEmpty(stack));
	stack->Top--;
}
DataType STFront(ST* stack)
{
	assert(stack);
	assert(stack->a);
	DataType* front = stack->a[stack->Top - 1];
	return front;
}
void STDestory(ST* stack)
{
	assert(stack);
	free(stack->a);
	stack->Top = stack->capaCity = 0;
}

 解题代码:

typedef struct {//定义队列结构
    ST PopStack;
    ST PushStack;
} MyQueue;


MyQueue* myQueueCreate() {
   MyQueue* obj = (MyQueue*)malloc(sizeof(MyQueue));//动态开辟出一个MyQueue
   if(obj == NULL)
   {
       perror("malloc fail");
       return;
   }
   STinit(&obj->PopStack);//初始化MyQueue里的队列
   STinit(&obj->PushStack);
   return obj;

}

void myQueuePush(MyQueue* obj, int x) {
    STpush(&obj->PushStack,x);//插入数据只能往PushStack里插入
}

int myQueuePeek(MyQueue* obj) {
    if(STEmpty(&obj->PopStack)){//当PopStack里的数据为空时往里面插入PushStack里的数据
        while(!STEmpty(&obj->PushStack))
        {
            int Top = STFront(&obj->PushStack);
            STpush(&obj->PopStack,Top);
            STPop(&obj->PushStack);
        }
    }
    int front = STFront(&obj->PopStack);
   // STPop(&obj->PopStack);
    return front;
}
int myQueuePop(MyQueue* obj) {
    int front = myQueuePeek(obj);
    STPop(&obj->PopStack);
    return front;
}


bool myQueueEmpty(MyQueue* obj) {//两个栈为空才是空
    return STEmpty(&obj->PopStack)&&STEmpty(&obj->PushStack);

}

void myQueueFree(MyQueue* obj) {
//销毁操作,销毁三者
STDestory(&obj->PopStack);
STDestory(&obj->PushStack);
free(obj);

}

3.用队列实现栈

题目:

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

实现 MyStack 类:

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

题目链接: https://leetcode.cn/problems/implement-stack-using-queues/

题目接口:

typedef struct {

} MyStack;


MyStack* myStackCreate() {

}

void myStackPush(MyStack* obj, int x) {

}

int myStackPop(MyStack* obj) {

}

int myStackTop(MyStack* obj) {

}

bool myStackEmpty(MyStack* obj) {

}

void myStackFree(MyStack* obj) {

}

分析:

用队列来实现栈还是像用栈实现队列一样,还是用两个队列来实现一个栈。就是用两者倒来倒去。只是这时不能够定义两个有特定功能的队列来分别实现插入与删除的操作。在用队列实现栈时要往有数据的队列里插入数据。出数据时要将不是空的的队列里的数据搞到不是空的队列里面。然后再来出数据。

代码:

创建队列代码:

typedef int Datatype;
typedef struct Qnode {
	struct Qnode* next;
	Datatype val;
}Qnode;
typedef struct Queue {
	Qnode* phead;
	Qnode* ptail;
	int size;
}Queue;

void QueueInit(Queue* pc)
{
	assert(pc);
	pc->phead = NULL;

	pc->ptail = NULL;
	pc->size = 0;
}
void PushQueue(Queue* pc,Datatype x)
{
	assert(pc);
	Qnode* newnode = (Qnode*)malloc(sizeof(Qnode));
	if (newnode == NULL)
	{
		perror("malloc fail/n");
		return;
	}
	newnode->val = x;
	newnode->next = NULL;
	if (pc->phead == NULL)
	{
		 //assert(pc->ptail );
		pc->phead = newnode;
		pc->ptail = newnode;

		
	}
	else
	{
		pc->ptail->next = newnode;
		pc->ptail = newnode;
	
	}
    pc->size++;
}
bool QEmpty(Queue* pc)
{
	return pc->phead == NULL;
}

void PopQueue(Queue* pc)//分一个节点和多个节点两种情况
{
	assert(pc);
	assert(!QEmpty(pc));
    if(pc->phead->next==NULL)
{
    free(pc->phead);
    pc->phead = pc->ptail;
    
}
else
{
   
	Queue* next = pc->phead->next;
	free(pc->phead);
	pc->phead = next;
}
	pc->size--;
}
Datatype QueueFront(Queue* pc)
{
	assert(pc);
    assert(pc->phead);
	Datatype val = pc->phead->val;
	return val;
}
Datatype QueueBack(Queue* pc)
{
	assert(pc);
    assert(pc->ptail);
	Datatype val = pc->ptail->val;
	return val;
}
int Qsize(Queue* pc)
{
	int size = pc->size;
	return size;
}
void QDestory(Queue* pc)
{
	assert(pc);
	Qnode* cur = pc->phead;
	while (cur)
	{
	Qnode* next = cur->next;
		free(cur);
		cur = next;
	}
	pc->phead = NULL;
	pc->ptail = NULL;
	pc->size = 0;
}

 解题代码:

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


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

void myStackPush(MyStack* obj, int x) {//往非空队列里导数据
   
   if(!QueueEmpty(&obj->q1))
   {
       QPush(&obj->q1,x);
   }
   else{
       QPush(&obj->q2,x);
   }
}

int myStackPop(MyStack* obj) {//移动非空队列里的数据到空队列中直至原来的非空队列中只剩一个数据然后删除再返回那一个数据
     Queue* Empty = &obj->q1;
    Queue* noEmpty = &obj->q2;
    if(!QueueEmpty(&obj->q1))
    {
       noEmpty = &obj->q1;
        Empty = &obj->q2;
    }
    while(QSize(noEmpty)>1)
    {
        int front = QFront(noEmpty);
        QPush(Empty,front);
        QPop(noEmpty);
    }

   int Top = QFront(noEmpty);
   QPop(noEmpty);
   return Top;
}

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

}

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

}

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

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

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

相关文章

【灾报警主机联网问题】

火灾报警主机联网问题一直是各消防项目中的难点,特别是管廊等长距离通讯中,如何保证通讯信号长期稳定可靠的运行是需要工程重点解决的问题,而LCAN-FOBR系列环网冗余式CAN光纤转换器提供二路光通道和一路CAN通道,实现CAN与光纤之间…

基于ENVI的遥感影像的非监督分类

ENVI包括了ISODATA和K-Mean两种非监督分类方法。 ISODATA(Iterative Self-Orgnizing Data Analysize Technique)是一种重复自组织数据分析技术,计算数据空间中均匀分布的类均值,然后用最小距离技术将剩余像元进行迭代聚合&#x…

常见分子直径

He 0.26 H2 0.289 NO 0.317 CO2 0.33 Ar 0.34 O2 0.346 N2 0.364 CO 0.376 CH4 0.38 C2H4 0.39 Xe 0.396 C3H8 0.43 SO2 0.28 气体分子 分子直径/nm 水0.27~0.32 氨0.365~0.38 苯0.65~0.68 乙烷0.40~0.47 乙烯…

华为OD机试真题 Python 实现【快速开租建站】【2023Q1 200分】,附详细解题思路

一、题目描述 当前IT部门支撑了子公司颗粒化业务,该部门需要实现为子公司快速开租建站的能力,建站是指在一个全新的环境部署一套IT服务。 每个站点开站会由一系列部署任务项构成,每个任务项部署完成时间都是固定和相等的,设为1。…

项目——学生信息管理系统5

目录 教师模块功能的实现 创建一个 Teacher 实体类 创建 添加老师界面 AddTeacherFrm 注意创建成 JInternalFrame 类型 页面的制作 给添加按钮绑定事件 提供一个重置表单功能 回到 MainFrm 添加教师管理的按钮 给添加教师按钮绑定事件 测试添加教师功能 创建教师信息管…

Day8——操作系统基础windows

文章目录 操作系统基础操作系统的定义 什么是windows 操作系统基础 操作系统的定义 什么是windows

gin RouterGroup 方法概览

路由组 RouterGroup是gin 里面的路由组,主要作用是实现gin的路由。 RouterGroup是嵌套在了Engine内部,实际上调用Engine的get,post等方式就是RouterGroup的实现。 另外RouterGroup还实现了如下两个接口: Engine相当于RouterGrou…

【Shell】自定义传入参数

授权 cd /Users/lion/Downloads/shell-test-demos chmod ux *.sh#!/bin/bashprintHelp() {echo "-p pic (required) path for pic"exit 1 }while getopts p:h OPT; docase $OPT inp) path"$OPTARG" ;;esac done# check api_key exists if [ -z "$pat…

多元回归预测 | Matlab海洋捕食者算法(MPA)优化极限学习机ELM回归预测,MPA-ELM回归预测,多变量输入模型

文章目录 效果一览文章概述部分源码参考资料效果一览 文章概述 多元回归预测 | Matlab海洋捕食者算法(MPA)优化极限学习机ELM回归预测,MPA-ELM回归预测,多变量输入模型 评价指标包括:MAE、RMSE和R2等,代码质量极高,方便学习和替换数据。要求2018版本及以上。 部分源码 %% …

计算机中丢失api-ms-win-core-path-l1-1-0dll

使用python自带工具打包exe文件夹时出现的错误。win10的exe文件放到win7上跑不出来。 本着找到这个dll文件放进去,但同事的win10打包的程序就可以放到win7上运行,所以改了python环境,把虚拟环境python版本改成了3.8,原来用的3.9不…

FFmpeg ~ 安装(附MetaRTC整合)

前言 本文会讲述FFmpeg下载/配置/编译/安装的完整流程,该流程并不复杂,因此本文的重点在于如何整合MetaRTC。MetaRTC的作用是令FFmpeg支持WebRTC推/拉流及回声消除功能(常规版本的FFmpeg是不支持该功能的),使得WebRTC音…

【万字长文】AMD Instinct MI300详细解析:超微半导体的光辉时刻

美国时间6月13日,AMD在美国加利福尼亚州旧金山举行了一场名为“数据中心与AI技术首演”的活动,并在主题演讲中介绍了数据中心的解决方案。 其中,宣布推出“AMD Instinct MI300系列加速器”(以下简称Instinct MI300系列&#xff0…

MidJourney v5.2 、Stable Diffusion XL 0.9 出图对比

最近两个最流行的AI图像生成器,Midjourney和Stable Diffusion,都发布了重大更新。Midjourney v5.2引入了许多新功能,包括“缩小”功能、“/缩短”命令、改进的图像质量等。 Stable Diffusion XL (SDXL) 0.9则专注于改善图像质量和构图。新模…

经典文献阅读之--R-PCC(基于距离图像的点云压缩方法)

0. 简介 对于激光雷达数据而言,虽然与2D图像相比,可以提供精确的物体深度信息,但也存在数据量大的问题,不便于数据存储或传输。在拿到离线数据分析的时候会发现我们很难拿到较长一段时间的激光数据,这就给我们问题的重…

抖音最新版本抓包

1.下载fiddler抓包工具 2.配置https抓包环境 3.抓包工具配置好了之后,我们确保手机和电脑在同一个局域网中 4.打电脑CMD 输入 ipconfig 查看电脑的ip地址 5.打开我们的手机设置代理 6.打开浏览器 输入:你的电脑ip:8888 下载证书 7.打开Re文件管理器(ps…

原来,绩效管理还能这么玩

早上好,我是老原。 最近,有个粉丝朋友来找我请教:他最近加入另外一家大型互联网公司,主要是负责领导力相关这块。他们现在也在做OKR实践,但是碰到了很多问题。 对此我并不觉得意外,因为这样的案例太多了。…

ModaHub魔搭社区:GPTCache的工作原理和为什么选择 GPTCache?

什么是 GPTCache? GPTCache 是一个开源工具,旨在通过实现缓存来提高基于 GPT 的应用程序的效率和速度,以存储语言模型生成的响应。GPTCache 允许用户根据其需求自定义缓存,包括嵌入函数、相似度评估函数、存储位置和驱逐等选项。…

《Opencv3编程入门》学习笔记—第十一章

《Opencv3编程入门》学习笔记 记录一下在学习《Opencv3编程入门》这本书时遇到的问题或重要的知识点。 第十一章 特征检测与匹配 一、SURF特征点检测 太复杂了!全是公式! (一)SURF算法概览 SURF,SpeededUp Rebus…

基于matlab使用点要素匹配在杂乱场景中检测对象(附源码)

一、前言 此示例演示如何在给定对象的参考图像的情况下检测杂乱场景中的特定对象。 此示例提供了一种基于查找参考和目标图像之间的点对应关系来检测特定对象的算法。它可以检测物体,尽管刻度变化或面内旋转。它对少量的面外旋转和遮挡也很鲁棒。这种对象检测方法…

Ansible练习

部署ansible练习 开始之前先使用student用户登录 登录命令:ssh studentworkstation 在workstation上运行lab deploy-review start命令,此脚本将确保受管主机在网络上访问。 然后开始验证控制节点上是否安装了ansible软件包,在运行anisble -…