232. 用栈实现队列
- 使用栈实现队列的下列操作:
- push(x) – 将一个元素放入队列的尾部。
- pop() – 从队列首部移除元素。
- peek() – 返回队列首部的元素。
- empty() – 返回队列是否为空。
思路:
栈为后进先出(LIFO),因此栈的pop()方法和top()方法都是针对栈顶元素,即append()的最后一个元素。
而队列的pop()方法和peek()方法是针对队列首部元素,即append()的第一个元素。
因此在用栈实现队列的pop()方法和peek()方法时,需要将输入栈元素依次出栈压入输出栈,实现元素反转,再使用栈的pop()方法。
利用两个堆栈,一个叫输入栈,一个叫输出栈。用于实现进入队列Push(x),出队列pop(),查看最后一个元素peek(),及判断是否为空empty()函数。每次从输入栈进,输出栈出。
push操作:将加入的元素添加到输入栈;
pop操作:从输出栈取走元素,输出栈没有元素时,将输入栈元素依次出栈压入输出栈,再从输出栈取出;
peek操作:访问输出栈栈顶元素,输出栈没有元素时,将输入栈元素依次出栈压入输出栈,再从输出栈取出;
empty为真的条件:两个栈都为空。
代码实现
class MyQueue:
def __init__(self):
"""
Initialize your data structure here.
"""
self.stackin = []
self.stackout = []
def push(self, x: int) -> None:
"""
Push element x to the back of queue.
"""
self.stackin.append(x)
def pop(self) -> int:
"""
Removes the element from in front of queue and returns that element.
"""
if len(self.stackout) == 0:
while self.stackin:
self.stackout.append(self.stackin.pop())
return self.stackout.pop()
def peek(self) -> int:
"""
Get the front element.
"""
if len(self.stackout) == 0:
while self.stackin:
self.stackout.append(self.stackin.pop())
return self.stackout[-1]
def empty(self) -> bool:
"""
Returns whether the queue is empty.
"""
if self.stackin or self.stackout:
return False
else:
return True
225. 用队列实现栈
- 使用队列实现栈的下列操作:
- push(x) – 元素 x 入栈
- pop() – 移除栈顶元素
- top() – 获取栈顶元素
- empty() – 返回栈是否为空
思路:
队列为先进先出(FIFO),要用队列实现栈,只需要在向栈中插入数据时,实现反转,即可使用队列的pop(0)方法。
使用一个队列,队列添加元素后,反转前n-1个元素,栈顶元素始终保留在队首
代码实现
class MyStack:
def __init__(self):
"""
Initialize your data structure here.
"""
self.q = []
def push(self, x: int) -> None:
"""
Push element x onto stack.
"""
self.q.append(x)
n = len(self.q)
while n > 1:
self.q.append(self.q.pop(0))
n -= 1
def pop(self) -> int:
"""
Removes the element on top of the stack and returns that element.
"""
return self.q.pop(0)
def top(self) -> int:
"""
Get the top element.
"""
return self.q[0]
def empty(self) -> bool:
"""
Returns whether the stack is empty.
"""
return not self.q
# Your MyStack object will be instantiated and called as such:
# obj = MyStack()
# obj.push(x)
# param_2 = obj.pop()
# param_3 = obj.top()
# param_4 = obj.empty()
155. 最小栈
- 设计一个支持 push,pop,top 操作,并能在常数时间内检索到最小元素的栈。
- push(x) – 将元素 x 推入栈中。
- pop() – 删除栈顶的元素。
- top() – 获取栈顶元素。
- getMin() – 检索栈中的最小元素。
思路:
- 对push增加功能:每次push比较一次,看当前值是否为新的最小值
- 对pop增加功能:每次pop操作,判断弹出的是否是最小值所在位置,是的话重新寻找最小值,时间复杂度 O ( n ) O(n) O(n)。
- 由2,需要自定义一个寻找最小值的函数。
push: O(1)时间, O(1)空间
pop: O(n)时间, O(1)空间
getMin和top:O(1)时间啦
代码实现
class MinStack:
def __init__(self):
"""
initialize your data structure here.
"""
self.__list = []
# 定义最小值索引
self.minindex = 0
def push(self, x: int) -> None:
self.__list.append(x)
# 判断新加入的值是否比原有最小值小,若成立,则修改最小值索引为 列表长度-1
if self.__list[self.minindex] > x:
self.minindex = len(self.__list) - 1
def pop(self) -> None:
# 设置最小值标志,若弹出的值为最小值,则重新寻找最小值
Flag = False
if self.minindex == len(self.__list) - 1:
Flag = True
if Flag:
# 栈顶为最小值,先弹出,再重新寻找最小值
num = self.__list.pop()
self.arrange()
else:
# 栈顶不为最小值,直接弹出
num = self.__list.pop()
return num
def top(self) -> int:
return self.__list[-1]
def getMin(self) -> int:
if self.__list == []:
return None
return self.__list[self.minindex]
def arrange(self):
# 寻找最小值函数
n = len(self.__list)
minindex = 0
for i in range(1, n):
if self.__list[i] < self.__list[minindex]:
minindex = i
self.minindex = minindex
# Your MinStack object will be instantiated and called as such:
# obj = MinStack()
# obj.push(x)
# obj.pop()
# param_3 = obj.top()
# param_4 = obj.getMin()