代码随想录算法训练营第十天| 232.用栈实现队列、 225. 用队列实现栈

本文讲述了在Python中如何使用列表实现栈和队列,以及在性能需求高的情况下使用collections.deque和标准库queue.Queue的优势。重点介绍了deque的高效操作和Queue的线程安全性。

在Python中,栈和队列可以使用列表(List)来实现,因为列表提供了在末尾进行添加append()和弹出pop()操作的高效方法。然而,这里有一些需要注意的事项:

  • 栈的实现
    栈是一种后进先出(Last In, First Out,LIFO)的数据结构。在Python中,可以使用列表的 append() 方法来在末尾添加元素,使用pop()方法从末尾移除元素。Python中的列表可以方便地用作栈。
    虽然在许多情况下,使用列表作为栈是非常方便的,但在某些需要高效的情况下,例如在频繁插入和删除操作的大型数据集合中,可能需要考虑使用 collections 模块中的 deque 类,它提供了 O(1) 复杂度的队列和栈操作。
  • 队列的实现
    表(List): 你可以使用列表的 append() 方法在队尾添加元素,使用 pop(0) 方法在队头删除元素。然而,在列表的开头执行 pop(0)操作会导致所有后续元素的移动,因此可能不是最高效的方法,特别是对于大型队列。如果队列很大,而且频繁地在队头执行删除操作,可能需要考虑使用其他数据结构。
    collections 模块中的 deque: collections 模块提供了 deque 类,它是一个双端队列的实现。deque 支持高效的队列操作,包括在两端进行元素的添加和删除。你可以使用 append()popleft() 方法在队尾添加元素和在队头删除元素,它们的时间复杂度均为 O(1)。因此,对于大型队列和需要频繁操作队头的情况,使用 deque 可能更合适。
    queue 模块中的 Queue: Python 的标准库中提供了 queue 模块,其中的 Queue 类是一个线程安全的队列实现。它支持多线程环境下的安全操作,提供了 put()get() 方法用于入队和出队操作。Queue 类的实现基于 deque。
    综上所述,对于一般情况下的队列操作,可以使用列表或者 collections 模块中的 deque。如果需要在多线程环境下操作队列,可以考虑使用 queue 模块中的 Queue 类。

232.用栈实现队列 - 🔗

讲解 - 🔗
💡刚开始没什么思路,后来看了一下文字解析稍微能自己写了。做题的时候发现list.pop()方法是有返回值的,返回被移除的元素的值,并且原始列表被修改,移除了指定位置的元素。所以通常会有list.append(list.pop())这种写法。可以直接将pop()的返回值作为参数传递给list.append()

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.stack_out:
           return self.stack_out.pop()
       else:
           for i in range(len(self.stack_in)):
               self.stack_out.append(self.stack_in.pop()) #list.pop()会返回被pop的值
           return self.stack_out.pop()

   def peek(self) -> int:
       tmp = self.pop()
       self.stack_out.append(tmp)
       return tmp

   def empty(self) -> bool:
       if self.stack_in or self.stack_out:
           return False
       else:
           return True
           
# 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()

最后一部分⬇️可以改写为return not (self.stack_in or self.stack_out)

def empty(self) -> bool:
	if self.stack_in or self.stack_out:
		return False
	else:
		return True

225. 用队列实现栈 - 🔗

讲解 - 🔗
💡在之前还不是特别明白这道题的意思的时候,我一直觉得这道题很简单,因为我想着直接用一个deque,不就可以同时实现先入先出和先入后出了吗?但是我没有考虑到是要用队列实现栈。也就是说deque只能使用append+popleft功能或者appendleft+pop功能,才能符合队列的先入先出。

方法一:一个deque
from collections import deque

class MyStack:
   # 把deque当成一个单向列表,由于遵循先入先出原则
   # 只能同时拥有append + popleft,或者append + pop
   def __init__(self):
       self.queue = deque()

   def push(self, x: int) -> None:
       self.queue.append(x)

   def pop(self) -> int:
       if self.empty():
           return None
       # 固定最后一个元素,将前面的所有元素按先入先出的顺序popleft再append到最后一个元素后面
       # 于是最后一个元素就变成了第一个元素
       for i in range(len(self.queue) - 1):
           self.queue.append(self.queue.popleft())
       return self.queue.popleft()

   def top(self) -> int:
       if self.empty():
           return None
       for i in range(len(self.queue) - 1):
           self.queue.append(self.queue.popleft())
       tmp = self.queue.popleft()
       self.queue.append(tmp)
       return tmp

   def empty(self) -> bool:
       if self.queue:
           return False
       else:
           return True
方法二:两个deque - 不同于用栈实现队列,另一个deque是用于备份的
from collections import deque

class MyStack:
    # 把deque当成一个单向列表,由于遵循先入先出原则,只能同时拥有append + popleft,或者append + pop
    def __init__(self):
        self.queue = deque()
        self.backup = deque()

    def push(self, x: int) -> None:
        self.queue.append(x)

    def pop(self) -> int:
        if self.empty():
            return None
        # 将先放入的元素移到backup备份
        for i in range(len(self.queue) - 1):
            self.backup.append(self.queue.popleft())
        # 获取到要移出的元素
        tmp  = self.queue.popleft()
        # 将备份里的元素按原有顺序重新放到队列里
        for i in range(len(self.backup)):
            self.queue.append(self.backup.popleft())
        return tmp

    def top(self) -> int:
        if self.empty():
            return None
        # 将先放入的元素移到backup备份
        for i in range(len(self.queue) - 1):
            self.backup.append(self.queue.popleft())
        # 获取到top元素
        tmp  = self.queue.popleft()
        # 将备份里的元素按原有顺序重新放到队列里
        for i in range(len(self.backup)):
            self.queue.append(self.backup.popleft())
        self.queue.append(tmp)
        return tmp

    def empty(self) -> bool:
        if self.queue:
            return False
        else:
            return True
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值