算法:
这道题就是用栈模拟队列。
举个例子理解:
输入: ["MyQueue", "push", "push", "peek", "pop", "empty"] [[], [1], [2], [], [], []] 输出: [null, null, null, 1, 1, false] 解释: MyQueue myQueue = new MyQueue(); //输入一个空字符串 myQueue.push(1); // queue is: [1]。插入队尾-1 myQueue.push(2); // queue is: [1, 2] 插入队尾-2 myQueue.peek(); // return 1。返回队首元素1 myQueue.pop(); // return 1, queue is [2] //从队首移除元素1 myQueue.empty(); // return false 判断队列是否为空:非空
在出队列时,队首先出,而栈中尾部元素先出,要想实现出队列操作,需要再借助一个栈(stack_out)
出队列时,把元素按照倒序放入stack_out,再stack_out.pop
比如数组[1,2],stack_out=[2,1],这样pop的就是队首1
调试过程:
class MyQueue:
def __init__(self):
stack_in = []
stack_out = []
def push(self, x: int) -> None:
stack_in.append.(x)
def pop(self) -> int:
#先判断队列是否为空
if self.empty:
return None
#由于peek操作,stack_out可能有值,此时直接返回stack_out里面的值即可
if stack_out:
return stack_out.pop
else:
for i in range(len(stack_in)):
stack_out.append(stack_in.pop)
return stack_out.pop
def peek(self) -> int:
#通过刚刚定义的pop函数从stack_out中得到队首元素的值
first = self.pop
#由于peek函数不改变队列,而pop把队首弹出来了,所以要把队首加回stack_out
stack_out.append(first)
return first
def empty(self) -> bool:
# stack_in和 stack_out都空,即空
return not (stack_in and stack_out)
# Your MyQueue object will be instantiated and called as such:
# obj = MyQueue()
# obj.push(x)
# param_2 = obj.pop()
# param_3 = obj.peek()
# param_4 = obj.empty()
原因:在代码中,需要将类内部的变量 `stack_in
` 和 `stack_out
` 前面加上 `self.
`,以表示它们是类的成员变量。另外,代码中的 `stack_in
` 和 `stack_out
` 是局部变量,需要改为 `self.stack_in
` 和 `self.stack_out
`,以正确引用类的成员变量。
而且,append函数使用不对,直接 self.stack_in.append(x)即可,append后面不要有“.”
修改后:
原因:调用函数时,应该在后面加上括号!
在代码中,`self.empty
` 和 `self.empty()
` 是两个不同的表达式。
-
`
self.empty
` 是一个属性(attribute),它是一个函数对象。在类定义中,`empty
` 是一个方法(函数),通过 `self.empty
` 可以访问到这个方法对象本身。这种用法通常用于在类内部进行方法的引用或传递。 -
`
self.empty()
` 是方法的调用(调用函数)。通过在方法名后面加上圆括号 `()
`,可以执行该方法并获取方法的返回值。在这个例子中,`self.empty()
` 调用了 `empty
` 方法,并返回了方法的返回值(一个布尔值)。
修改后:
class MyQueue:
def __init__(self):
self.stack_in = []
self.stack_out = []
def push(self, x: int) -> None:
self.stack_in.append(x)
def pop(self) -> int:
#先判断队列是否为空
if self.empty():
return None
#由于peek操作,stack_out可能有值,此时直接返回stack_out里面的值即可
if self.stack_out:
return self.stack_out.pop()
else:
for i in range(len(stack_in)):
self.stack_out.append(stack_in.pop)
return self.stack_out.pop()
def peek(self) -> int:
#通过刚刚定义的pop函数从stack_out中得到队首元素的值
first = self.pop()
#由于peek函数不改变队列,而pop把队首弹出来了,所以要把队首加回stack_out
self.stack_out.append(first)
return first
def empty(self) -> bool:
# stack_in和 stack_out都空,即空
return not (self.stack_in and self.stack_out)
# Your MyQueue object will be instantiated and called as such:
# obj = MyQueue()
# obj.push(x)
# param_2 = obj.pop()
# param_3 = obj.peek()
# param_4 = obj.empty()
原因:之前的调用还没全改过来。empty处应该把and改成or,只要有一个非空,就非空,所以非空的逻辑是or ,空就是非空前面加 not
正确代码:
class MyQueue:
def __init__(self):
self.stack_in = []
self.stack_out = []
def push(self, x: int) -> None:
self.stack_in.append(x)
def pop(self) -> int:
#先判断队列是否为空
if self.empty():
return None
#由于peek操作,stack_out可能有值,此时直接返回stack_out里面的值即可
if self.stack_out:
return self.stack_out.pop()
else:
for i in range(len(self.stack_in)):
self.stack_out.append(self.stack_in.pop())
return self.stack_out.pop()
def peek(self) -> int:
#通过刚刚定义的pop函数从stack_out中得到队首元素的值
first = self.pop()
#由于peek函数不改变队列,而pop把队首弹出来了,所以要把队首加回stack_out
self.stack_out.append(first)
return first
def empty(self) -> bool:
# stack_in和 stack_out都空,即空
return not (self.stack_in or self.stack_out)
# Your MyQueue object will be instantiated and called as such:
# obj = MyQueue()
# obj.push(x)
# param_2 = obj.pop()
# param_3 = obj.peek()
# param_4 = obj.empty()
时间空间复杂度:
- 时间复杂度: push和empty为O(1), pop和peek为O(n)
- 空间复杂度: O(n)