一、括号匹配问题

1、题目要求:

2、大体思路

遍历这个字符串,如果是左括号就让它入栈,如果是右括号就让它和栈顶元素进行匹配(前提是栈中有元素),匹配成功的话就让栈顶元素出栈,匹配失败就返回false,直到遍历完字符串,如果遍历完了栈中没有元素,则返回true。

3、代码实现

bool isValid(char * s){Stack stack;StackInit(&stack);//初始化int i = 0;while(s[i] != '\0'){//入栈if(s[i] == '{' || s[i] == '[' || s[i] == '('){StackPush(&stack,s[i]);}else{//栈为空时if(StackEmpty(&stack)){StackDestroy(&stack);  //销毁栈return false;}if((StackTop(&stack) == '(' && s[i] == ')') ||(StackTop(&stack) == '{' && s[i] == '}') ||(StackTop(&stack) == '[' && s[i] == ']')){  StackPop(&stack);   //匹配的话出栈}else{//不匹配StackDestroy(&stack);return false;}}i++;}//遍历完后栈为空if(StackEmpty(&stack)){StackDestroy(&stack);return true;}StackDestroy(&stack);return false;
}

二、用队列实现栈

1、题目要求:

2、大体思路

用两个队列q1和q2来实现,要实现入栈的话可以选不为空的队列进行入队列操作(开始两个队列都可以),假设现在元素都在q1中,要实现出栈的话把q1中的元素放入q2中,直到q1中剩一个一个元素,在让它出队列。

3、代码实现

//用两个队列实现栈
typedef struct {Queue q1;Queue q2;
} MyStack;MyStack* myStackCreate() {MyStack* ms = (MyStack*)malloc(sizeof(MyStack));if(ms == NULL){return NULL;}QueueInit(&ms->q1);QueueInit(&ms->q2);return ms;
}void myStackPush(MyStack* obj, int x) {//给不为空的队列加入元素,模拟入栈if(QueueEmpty(&obj->q1) ){QueuePush(&obj->q2,x);}else{QueuePush(&obj->q1,x);}
}int myStackPop(MyStack* obj) {//当q1为空时,把q2中的元素放入q1中直到q2中只剩一个元素,然后q2再出队列,模拟出栈int ret = 0;if(QueueEmpty(&obj->q1)){while(QueueSize(&obj->q2) != 1){QueuePush(&obj->q1,QueueFront(&obj->q2));QueuePop(&obj->q2);}ret = QueueFront(&obj->q2);QueuePop(&obj->q2);}else{while(QueueSize(&obj->q1) != 1){QueuePush(&obj->q2,QueueFront(&obj->q1));QueuePop(&obj->q1);}ret = QueueFront(&obj->q1);QueuePop(&obj->q1);}return ret;
}
//栈顶元素相当于是队尾元素
int myStackTop(MyStack* obj) {if(QueueEmpty(&obj->q1)){return QueueBack(&obj->q2);}else{return QueueBack(&obj->q1);}
}bool myStackEmpty(MyStack* obj) {if(QueueSize(&obj->q1) == 0 && QueueSize(&obj->q2) == 0){return true;}return false;
}void myStackFree(MyStack* obj) {QueueDestroy(&obj->q1);QueueDestroy(&obj->q2);free(obj);
}

三、用栈实现队列

1、题目要求

2、大体思路

用两个栈s1和s2来实现,s1用来模拟入队列,s2用来模拟出队列。实现入队列就直接对s1进行入栈操作;出队列的话,先判断s2中是否有元素,如果没有则把s1中的元素放入s2中,然后再对s2进行出栈操作。

3、代码实现

typedef struct {//s1用来入队列,s2用来出队列Stack s1;  Stack s2;
} MyQueue;MyQueue* myQueueCreate() {MyQueue* q = (MyQueue*)malloc(sizeof(MyQueue));if(q == NULL){return NULL;}StackInit(&q->s1);StackInit(&q->s2);return q;
}
//入队列
void myQueuePush(MyQueue* obj, int x) {StackPush(&obj->s1,x);
}
//出队列
int myQueuePop(MyQueue* obj) {//s2不为空的话先把s1中的元素搬移到s2中if(StackEmpty(&obj->s2)){while(!StackEmpty(&obj->s1)){StackPush(&obj->s2,StackTop(&obj->s1));StackPop(&obj->s1);}}int ret =  StackTop(&obj->s2);StackPop(&obj->s2);return ret;}
//返回对头元素,和出队列差不多
int myQueuePeek(MyQueue* obj) {if(StackEmpty(&obj->s2)){while(!StackEmpty(&obj->s1)){StackPush(&obj->s2,StackTop(&obj->s1));StackPop(&obj->s1);}}return StackTop(&obj->s2);
}bool myQueueEmpty(MyQueue* obj) {if(StackEmpty(&obj->s1) && StackEmpty(&obj->s2)){return true;}return false;
}void myQueueFree(MyQueue* obj) {if(obj != NULL){StackDestroy(&obj->s1);StackDestroy(&obj->s2);free(obj);}
}

四、设计一个循环队列

1、题目要求

2、大体思路

循环队列是用顺序结构存储的。用两个指针来标记对头和队尾,如图:

但这样会有一个问题,就是在队列为空和队列满了的情况下,rear和front都重合了,这样就不能判断是队列满了还是队列为空。解决这个问题有三种方法:

方法一: 我们可以少用一个存储空间,如图所示,这样就代表队列已经满了。

方法二:用一个flag进行标记,开始设为0,插入元素时将flag设为1,删除元素时设为0;这样当front等于rear时,判断一下flag就行了。

方法三:使用一个count进行计数,只有count为零时队列为空。

3、代码实现

这里用的是方法三

typedef struct {int* array;//存储数据int front; //对头int rear;  //队尾int count; //计数int N; //队列容量
} MyCircularQueue;//初始化
MyCircularQueue* myCircularQueueCreate(int k) {//先给队列申请空间MyCircularQueue* q = (MyCircularQueue*)malloc(sizeof(MyCircularQueue));if(q == NULL ){return NULL;}//再给队列里的数组申请空间q->array = (int*)malloc(sizeof(int) * k);if(q->array == NULL){//如果失败,要先释放队列的空间,注意代码的严谨性free(q);return NULL;}q->front = q->rear = q->count = 0;q->N = k;return q;
}//判断队列是否为空
bool myCircularQueueIsEmpty(MyCircularQueue* obj) {return 0 == obj->count;
}//判断队列是否满了
bool myCircularQueueIsFull(MyCircularQueue* obj) {return obj->count == obj->N;
}//入队列
bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {if(myCircularQueueIsFull(obj)){return false;}obj->array[obj->rear] = value;if(obj->rear == obj->N - 1){obj->rear = 0;}else{obj->rear++;}obj->count++;return true;
}
//出队列
bool myCircularQueueDeQueue(MyCircularQueue* obj) {if(myCircularQueueIsEmpty(obj)){return false;}if(obj->front == obj->N - 1){obj->front = 0;}else{obj->front++;}obj->count--;return true;
}int myCircularQueueFront(MyCircularQueue* obj) {if(myCircularQueueIsEmpty(obj)){return -1;}return obj->array[obj->front];
}int myCircularQueueRear(MyCircularQueue* obj) {if(myCircularQueueIsEmpty(obj)){return -1;}//注意获取队尾元素的计算方法return obj->array[(obj->rear - 1 + obj->N) % obj->N];
}//释放空间
void myCircularQueueFree(MyCircularQueue* obj) {if(obj){if(obj->array){free(obj->array);}free(obj);nhj }
}

栈和队列常见oj题(括号匹配问题、栈实现队列、队列实现栈、设计循环队列)相关推荐

  1. C语言【数据结构】栈和队列【OJ题(C++)、选择题】

    目录 一.OJ题 1.225. 用队列实现栈 2.232. 用栈实现队列 3.622. 设计循环队列 4.20. 有效的括号 二.选择题 1.下列关于栈的叙述正确的是(B) 2.一个栈的入栈序列为AB ...

  2. 2.2栈的另一个应用:括号匹配

    2.2栈的另一个应用:括号匹配 1.LeetCode官网 美网:https://leetcode.com/ 中文网 :https://leetcode-cn.com/ 英语不咋地,所以选择此处选择中文 ...

  3. 力扣题库设计循环队列

    题目要求: 设计你的循环队列实现. 循环队列是一种线性数据结构,其操作表现基于 FIFO(先进先出)原则并且队尾被连接在队首之后以形成一个循环.它也被称为"环形缓冲器". 循环队列 ...

  4. c++数据结构中 顺序队列的队首队尾_yiduobo的每日leetcode 622.设计循环队列

    祖传的手艺不想丢了,所以按顺序写一个leetcode的题解.计划每日两题,争取不卡题吧. 622.设计循环队列https://leetcode-cn.com/problems/design-circu ...

  5. Leetcode 622. 设计循环队列

    Leetcode 622. 设计循环队列学习 分析 代码 参考链接 分析 循环队列,自己做题时没考虑怎么实现,可以通过索引下标除以数组的长度实现循环.循环队列的队首元素和队尾元素是动态变化的,删除一个 ...

  6. 【Java】 LeetCode 622. 设计循环队列 (有关实现循环队列的讲解)

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

  7. socketmq 设置队列大小_LeetCode 622:设计循环队列 Design Circular Queue

    LeetCode 622:设计循环队列 Design Circular Queue 首先来看看队列这种数据结构: 队列:先入先出的数据结构 在 FIFO 数据结构中,将首先处理添加到队列中的第一个元素 ...

  8. 622. 设计循环队列(C实现)

    题目 题目链接:622. 设计循环队列 思路 设计循环队列有两种实现方式 第一种是使用数组实现: 第二种是使用单链表实现: 而设计循环队列不管是使用数组实现还是使用单链表实现,都需要给数组预留出一个空 ...

  9. 力扣622,设计循环队列

    文章目录 题目描述 题目分析 使用数组的方式来解题 使用链表的方式 题目描述 设计你的循环队列实现. 循环队列是一种线性数据结构,其操作表现基于 FIFO(先进先出)原则并且队尾被连接在队首之后以形成 ...

最新文章

  1. BUILD 2015: Visual Studio对GitHub的支持
  2. [导入]ubuntu全面介绍 与 ubuntu截图
  3. 判断当前窗口是否是全屏的山寨版和官方版
  4. 学习笔记:定积分的求解(矩形法)
  5. 过滤器(Filter)的实现方式
  6. AI图像合成技术如何用于数字营销和创意领域?
  7. 背景动态线条js特效html5代码
  8. 票据识别android代码,Android 百度AI开放平台-文字识别-财务票据文字识别
  9. 前端webap下新增后缀名字类型。前台报错404,访问不到的解决办法是:
  10. ultraiso制作u盘启动盘教程图文详解
  11. 网络安全突发事件应急处置工作预案
  12. 驾考宝典java_驾考宝典java
  13. 【笔记】移植ezSIFT顺手搭建个全景照片合成器
  14. Linux下运行python自动化脚本
  15. 忆阻器的概念和实现原理
  16. 第二章 一波未平 校园江湖
  17. 【Proteus仿真】4X4矩阵按键显示0-F
  18. R语言ggplot2可视化自定义图例(legend)示例点的大小实战
  19. Android开发-直播视讯(2)-ijkplayer-基础知识
  20. 【云和恩墨大讲堂】戴明明 - 基于 PCIE 闪存卡的 Oracle 数据库使用

热门文章

  1. 英译汉需要注意的几点
  2. 照相机闪光灯的全球与中国市场2022-2028年:技术、参与者、趋势、市场规模及占有率研究报告
  3. 安装pycocotools时遇到ERROR: Could not build wheels for pycocotools which use PEP 517 and cannot be instal
  4. rust 使用 ffi 调用 C 静态链接库
  5. java计算机毕业设计ssm“安家”儿童福利院管理系统(源码+系统+mysql数据库+Lw文档)
  6. java验证文本域对IP,端口号的验证
  7. 局域网多媒体教学系统中基于JAVA的屏幕监控
  8. 【Redis过期策略/内存淘汰机制/对过期Key的处理】
  9. Oracle 数据库监听日志过大,怎么清除?
  10. 小机扩容磁盘方法(AIX 6.0)