1.用两个栈实现队列
问题描述
用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型。
考察点:栈、队列的性质
思路
- 用两个先进后出,实现先进先出。(入队,出队)
- “出队”:当S2不空,则对S2做弹出;若S2为空,则把S1中所有元素,逐个压入S2,最后对S2做弹出。
- “入队:当S2空,直接对S1添加;当S2不空,也没关系,因为总会先将S2中弹空,才对S2执行压入,所以不会乱序。
class Solution1:
def __init__(self):
self.s1 = []
self.s2 = []
def push(self, node):
#入队,跟S2状态无关
self.s1.append(node)
def pop(self):
# 出队,要分S2空与否;
#S2空,将S1中所有元素弹出到S2,再对S2弹出一个。
if self.s2 == []:
while self.s1:
self.s2.append(self.s1.pop())
return self.s2.pop()
# 当S2不空,直接对S2弹出
return self.s2.pop()
if __name__ == '__main__':
s = Solution1()
s.push([1,2,3])
print s.pop()
[1, 2, 3]
2.包含min函数的栈
问题描述
定义栈的数据结构,请在该类型中实现一个能够得到栈最小元素的min函数
考察点
- 最初可能想用‘变量’保存最小元素,但是弹出最小后,次小没办法获取
- 引入辅助栈
测试用例
- 压入的比最小的大/小
- 弹出的是/否为当前最小值
思路
- 压入时,另外用辅助栈存储当前的最小值
- 弹出时,若弹出的为最小,则同时弹出两个栈;否则,只弹出数据栈;
class Solution2:
def __init__(self):
self.stack = []
self.minstack = []
def push(self, node):
# write code here
self.stack.append(node)
if len(self.minstack)==0 or node<=self.minstack[-1]:
self.minstack.append(node)
def pop(self):
# write code here
if self.stack[-1]==self.minstack[-1]:
self.minstack.pop(-1)
self.stack.pop(-1)
def top(self):
# write code here
return self.stack[-1]
def min(self):
# write code here
return self.minstack[-1]
if __name__ == '__main__':
s = Solution2()
s.push([3])
print s.min()
s.push([4])
print s.min()
s.push([2])
print s.min()
[3]
[3]
[2]
3.栈的压入、弹出序列
问题描述
输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。(注意:这两个序列的长度是相等的)
测试用例
- 两个空指针
- 是/非弹出序列
思路
引入辅助栈存储当前序列,弹出时分两种情况
1. 弹出元素为辅助栈栈顶:直接弹出
2. 弹出元素非辅助栈栈顶:将未入栈元素入栈,直到找到要弹出的元素;否则为‘非弹出序列’
# -*- coding:utf-8 -*-
class Solution:
def IsPopOrder(self, pushV, popV):
# write code here
if not pushV or len(pushV)!= len(popV):
return False
stack = []
for i in pushV:
stack.append(i)
while len(stack) and stack[-1] == popV[0]:
stack.pop() # 弹出最后一个
popV.pop(0) # 弹出第一个
if len(stack):
return False
return True
if __name__ == '__main__':
s = Solution()
print s.IsPopOrder([1,2,3,4,5],[4,3,5,1,2])
False