刷题记录(6)栈与队列相关操作
一、判断字符匹配
读题其实不老有感觉,就是左括号必须用与之对应的右括号去对应,也就是(),[],{},可以嵌套,但是必须对应顺序:[()],这样就不行:[{)]。
大致思路
这里提供一种思路,如果用栈来实现的话,情况就是这样的:
只入栈左括号,右括号就和上次入栈的左括号对比,匹配就把对比过的左括号出栈并继续遍历,不匹配返回true。
就像这样:
左括号就入栈,右括号就对比,相匹配那继续遍历,不匹配直接返回false。
代码展示:
栈的实现直接用写过的代码:数据结构(5)线性表-栈-CSDN博客
细节优化
但是一点提交就出现问题了:
只有左括号,等于没有右括号去匹配。
我们代码中分支只有如果是右括号,那就判断,没有右括号,遍历到'\0'直接退出了。
如果正常的话这种情况栈非空,说明没有匹配上,那么返回值修改一下:
之后提交又报错了:
只有右括号输入,一句一句看到底哪错了:
对照用例就容易发现,如果只有右括号没有左括号的话,等于栈没有元素,你还取什么栈顶元素,所以加个分支,如果栈为空。且是右括号,那就直接返回false。
又怼了个小if,如果都是右括号了,但是栈里面都没有元素,那么直接返回false。
二、用队列实现栈
第一次写生成这么多方法的题,大概意思就是,创建两个队列实现栈的Push,Pop,Top,Empty四种操作,至于最最底层的队列还是复制粘贴写过的代码:数据结构(6)线性表-队列-CSDN博客
one by one
栈的结构体直接创建两个队列即可,题意就是两个队列实现:
接着
这个Create方法是让人创建并返回一个队列实现栈的栈的指针,而其实也就是创建两个队列呗,队列的初始化写的好好的,直接调用:
剩下的有几个比较重要的,画图来说:
题目的意思是这样,重点有几个,比如入栈和出栈:
队列的插入删除特点是:先进先出
栈的插入删除特点是:后进先出
假如是这样的:
假如要入栈个1234,放到其中一个队列里的话是这样的:
这样的话出栈就是出q1这个队列,肯定是不可以的,因为队列只能先进先出,顺序是1234而栈要求的顺序是4321,那么肯定还得借助q2来回倒:
这种情况大概说一下就是非空队列要把前size-1个元素放到队列里,再出元素,这样的话就可以达到pop栈顶的效果,这个玩意有点像最近看见的一个小游戏的推广:
就是来回倒,最后每个瓶子里只有一种颜色。
这里我们这么做就有点这意思。
需要用到的函数,检验队列是否为空,非空队列的Size,Push和Pop。
这些函数都已经有了,那么出栈算是实现了,但是入栈该往哪里入呢?
其实就俩选择,是往空的里面入,还是往非空里面入:
假如说插入5。
插入完继续删:
如果往空的里面插,你肯定还得倒腾吧,非空的q2全部移到q1是什么结果:
倒腾完q1就是5 1 2 3后进先出应该是5先出,直接出就行了,但是这样的话还得记录非空变空,如果不止一个,假如说插入个5 6,结果就是再出的话得出6,那就还得倒,但是这次可没有空和非空的差别,还得专门记录一下上次插入的队列。
如果插入到非空呢,q2就会是1 2 3 5,假如说这个时候继续删,这样倒腾回q1个123,再出5,删除代码是一样的。
所以删还是倒腾着删,插的话就往非空插,这样就不用监视上次往哪插了。
这两段代码就水灵灵的写完了,就是找非空链表,一个是插,一个是移。
剩下的没啥可说了,取栈顶其实就是取非空的队尾,判断栈是否为空就判断俩队列是否为空,销毁纯调用我们写的函数基本:
一弄就是通过:
三、用栈实现队列
基本不用说什么废话了,和队列实现栈的操作差不老多,就看看怎么用俩栈实现队列的插入删除即可:
假如说是初始为1234:
出队列我们还想要1234,但是现在只能4321(实际上有好多出栈,但是假设插好是1234就只能4321了),那就倒腾到另一个里面看看怎么个事:
刚好符合要求,那么干脆一个叫Pushst,一个叫Popst。
插入就往插入栈里面进,删除就进到删除栈里。
当然,假如中间我们还得插入数据呢?
比如:
一看便知,如果出队列过程中又插个5,只有等popst为空时,才能将pushst的数据移到popst里,否则就会破坏顺序。
难点都突破以后就直接给出一系列代码了:
确实只有pop麻烦一点,但是画图就非常清晰了。