剑指offer 2.3.5 栈和队列
参考:
2.3.5 栈和队列
1 基础知识
- 栈是一个不考虑排序的数据结构,我们需要 O(n) 时间才能找到栈中最大或者最小的元素。
- 如果想要在O(1)时间内得到栈的最大或者最小值,我们需要对栈做特殊的设计,详见面试题21“包含min函数的栈”。
- 构建一个辅助栈,保存当前最小值,从其中一次弹出最值。
- 队列的特点是先进先出,即第一个进入队列的元素将会第一个出来。
- 在2.3.4节介绍的树的宽度优先遍历算法中,我们在遍历某一层树的结点时,把结点的子结点放到一个队列里,以备下一层结点的遍历。
2 用两个栈实现一个队列
用两个栈实现一个队列。队列的声明如下,请实现它的两个函数appendTail和deleteHead,分别完成在队列尾部插入结点和在队列头部删除结点的功能。
解题思路
题目理解:
操作这两个“先进后出”的栈实现一个“先进先出”的队列CQueue。
- 栈A用来入队列
- 将所有新来的数据依次压入栈A
- 栈B用来出队列。
- 当栈B为空时,将栈A中的元素从栈顶依次弹出pop,并依次压入push栈B,此时为下面所述B非空的情况
- 当栈B非空时,将栈B中的元素依次弹出,即符合“先进先出”原则
牛客网:面试题07
class Solution:
def __init__():
self.stack1 = []
self.stack2 = []
def push(self, node):
self.stack1.append(node)
# write code here
def pop(self):
if self.stack2:
return self.stack2.pop()
while self.stack1:
self.stack2.push(self.stack1.pop())
return self.stack2.pop()
3 用两个队列实现一个栈
解题思路
queue1和queue2的规律:先入先出
queue1弹出元素顺序:a-b-c,遇到c时,删除c,即代表出栈
注意:
- 入队列时也要进行判断,只放入非空的队列
- 出队列时,根据当前非空队列的长度,找到队列中的最后一个元素,将其删除
- pop() 默认弹出 idx=-1 的值,指定 idx=0 时,弹出第一个元素,即第一个压入queue1的元素
class Solution:
def __init__():
self.queue1 = []
self.queue2 = []
def push(self, node):
# 将新来的元素放入非空队列中
if self.queue2 == []:
self.queue1.append(x)
else:
self.queue2.append(x)
def pop(self):
if not self.queue1 and not self.queue2:
return
# 找到非空队列的长度,以便找到非空队列最后一个元素的位置
if self.queue1:
for i in range(len(self.queue1)-1):
# pop()默认弹出idx=-1的值,指定0时,弹出第一个元素,即第一个压入queue1的元素
self.queue2.append(self.queue1.pop(0))
return self.queue1.pop()
# if self.queue2:可以省略,因为queue1与queue2最多只能有一个非空
else:
for i in range(len(self.queue2)-1):
self.queue1.append(self.queue2.pop(0))
return self.queue2.pop()