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

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

一、232.用栈实现队列

文档链接:代码随想录

题目链接:232.用栈实现队列

视频讲解:视频讲解

题目描述:

请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(pushpoppeekempty):

实现 MyQueue 类:

  • void push(int x) 将元素 x 推到队列的末尾
  • int pop() 从队列的开头移除并返回元素
  • int peek() 返回队列开头的元素
  • boolean empty() 如果队列为空,返回 true ;否则,返回 false

说明:

  • 只能 使用标准的栈操作 —— 也就是只有 push to top, peek/pop from top, size, 和 is empty 操作是合法的。
  • 你所使用的语言也许不支持栈。你可以使用 list 或者 deque(双端队列)来模拟一个栈,只要是标准的栈操作即可。

示例 1:

输入:
["MyQueue", "push", "push", "peek", "pop", "empty"]
[[], [1], [2], [], [], []]
输出:
[null, null, null, 1, 1, false]

解释:
MyQueue myQueue = new MyQueue();
myQueue.push(1); // queue is: [1]
myQueue.push(2); // queue is: [1, 2] (leftmost is front of the queue)
myQueue.peek(); // return 1
myQueue.pop(); // return 1, queue is [2]
myQueue.empty(); // return false

提示:

  • 1 <= x <= 9
  • 最多调用 100pushpoppeekempty
  • 假设所有操作都是有效的 (例如,一个空的队列不会调用 pop 或者 peek 操作)

进阶:

  • 你能否实现每个操作均摊时间复杂度为 O(1) 的队列?换句话说,执行 n 个操作的总时间复杂度为 O(n) ,即使其中一个操作可能花费较长时间。

代码:

思路:理解栈与队列的原理与区别。

    • 先进后出,后进先出
    • 只允许在固定的一端进行插入和删除操作
    • 压栈(入栈)指的是将元素放入栈顶的操作
    • 出栈则是将栈顶元素取出
  • 队列
    • 先进先出
    • 入队指的是将元素放入队尾
    • 出队指的是将队首元素取出
class MyQueue:
    def __init__(self):
        self.stack_in = []  # 输入栈,用于push操作
        self.stack_out = []  # 输出栈,用于pop和peek操作

    def push(self, x: int) -> None:
        self.stack_in.append(x)  # 将元素x入栈

    def pop(self) -> int:
        if not self.stack_out:  # 如果输出栈为空
            while self.stack_in:  # 将输入栈的元素一次弹出并压入到输出栈里
                self.stack_out.append(self.stack_in.pop())
        return self.stack_out.pop()  # 弹出输出栈的栈顶元素

    def peek(self) -> int:
        if not self.stack_out:  # 如果输出栈为空
            while self.stack_in:  # 将输入栈的元素一次弹出并压入到输出栈里
                self.stack_out.append(self.stack_in.pop())
        return self.stack_out[-1]  # 返回栈顶元素,即为队列的开头元素

    def empty(self) -> bool:
        return not self.stack_in and not self.stack_out
        # 如果输入栈和输出栈都为空,则队列为空,返回 True;否则,返回 False


# 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()

二、225.用队列实现栈

文档链接:代码随想录

题目链接:225.用队列实现栈

视频讲解:视频讲解

题目描述:

请你仅使用两个队列实现一个后入先出(LIFO)的栈,并支持普通栈的全部四种操作(pushtoppopempty)。

实现 MyStack 类:

  • void push(int x) 将元素 x 压入栈顶。
  • int pop() 移除并返回栈顶元素。
  • int top() 返回栈顶元素。
  • boolean empty() 如果栈是空的,返回 true ;否则,返回 false

注意:

  • 你只能使用队列的基本操作 —— 也就是 push to backpeek/pop from frontsizeis empty 这些操作。
  • 你所使用的语言也许不支持队列。 你可以使用 list (列表)或者 deque(双端队列)来模拟一个队列 , 只要是标准的队列操作即可。

示例:

输入:
["MyStack", "push", "push", "top", "pop", "empty"]
[[], [1], [2], [], [], []]
输出:
[null, null, null, 2, 2, false]

解释:
MyStack myStack = new MyStack();
myStack.push(1);
myStack.push(2);
myStack.top(); // 返回 2
myStack.pop(); // 返回 2
myStack.empty(); // 返回 False

提示:

  • 1 <= x <= 9
  • 最多调用100pushpoptopempty
  • 每次调用 poptop 都保证栈不为空

**进阶:**你能否仅用一个队列来实现栈。

代码:

思路:使用双端队列(deque)来实现栈的基本操作。双端队列是一个可以从两端插入和删除的序列,因此它可以用来模拟栈的行为。

  • 双队列
from collections import deque
class MyStack:
 
    def __init__(self):  # 初始化方法,当创建MyStack类的实例时会自动调用。  
        self.queue1 = deque()  # 创建一个名为queue1的deque对象,用于模拟栈的底层数据结构。  
        self.queue2 = deque()  # 创建一个名为queue2的deque对象,用于在pop操作时交换两个队列。  
  
    def push(self, x: int) -> None:  # push方法,用于向栈顶添加一个整数x。  
        self.queue1.append(x)  # 将x添加到queue1的右侧。  
  
    def pop(self) -> int:  # pop方法,用于从栈顶删除一个整数并返回它。  
        if not self.queue2:  # 如果输出栈为空
            while len(self.queue1) > 1:  # 遍历queue1的左侧元素(除了最后一个)。  
                self.queue2.append(self.queue1.popleft())  # 将每个元素从queue1左侧移除并添加到queue2的右侧。  

            # 交换两个队列的对象引用,使得原本的queue1现在指向被pop操作后的queue2,而原本的queue2现在指向原始的空队列。 
            self.queue1, self.queue2 = self.queue2, self.queue1
        return self.queue2.popleft()  # 返回被pop操作后的队列的第一个元素(即原来的栈顶元素)。
          
    def top(self) -> int:  # top方法,用于返回栈顶的整数,但不删除它。
        return self.queue1[-1]  # 返回queue1中的最后一个元素,即原来的栈顶元素。
  
    def empty(self) -> bool:  # empty方法,用于检查栈是否为空。
        return not self.queue1  # 如果queue1为空,则返回True,否则返回False。

# 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()
  • 单队列
from collections import deque
class MyStack:
    # 初始化方法,当创建MyStack类的实例时会自动调用
    def __init__(self):
        # 创建一个名为queue的deque对象,用于模拟栈的底层数据结构
        self.queue = deque()

    # push方法,用于向栈顶添加一个整数x
    def push(self, x: int) -> None:
        # 将x添加到queue的右侧
        self.queue.append(x)

    # pop方法,用于从栈顶删除一个整数并返回它
    def pop(self) -> int:
        # 如果栈为空(即queue为空),则返回None
        if self.empty():
            return None
        # 循环地将元素从queue的左侧移到右侧,直到只剩下一个元素。这样做的目的是为了保持deque的有序性,以便能够正确地返回栈顶元素。
        for i in range(len(self.queue) - 1):
            self.queue.append(self.queue.popleft())
        # 返回从queue左侧弹出的元素(即原来的栈顶元素)
        return self.queue.popleft()

    # top方法,用于返回栈顶的整数,但不删除它
    def top(self) -> int:
        # 返回queue的最后一个元素,即栈顶元素。这里不需要进行任何检查,因为如果栈为空,pop和top方法会返回None。
        return self.queue[-1]

    # empty方法,用于检查栈是否为空
    def empty(self) -> bool:
        # 如果queue为空,则返回True,否则返回False。
        return not self.queue

# 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()
  • 9
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
第二十二算法训练营主要涵盖了Leetcode题目中的三道题目,分别是Leetcode 28 "Find the Index of the First Occurrence in a String",Leetcode 977 "有序数组的平方",和Leetcode 209 "长度最小的子数组"。 首先是Leetcode 28题,题目要求在给定的字符串中找到第一个出现的字符的索引。思路是使用双指针来遍历字符串,一个指向字符串的开头,另一个指向字符串的结尾。通过比较两个指针所指向的字符是否相等来判断是否找到了第一个出现的字符。具体实现代码如下: ```python def findIndex(self, s: str) -> int: left = 0 right = len(s) - 1 while left <= right: if s[left == s[right]: return left left += 1 right -= 1 return -1 ``` 接下来是Leetcode 977题,题目要求对给定的有序数组中的元素进行平方,并按照非递减的顺序返回结果。这里由于数组已经是有序的,所以可以使用双指针的方法来解决问题。一个指针指向数组的开头,另一个指针指向数组的末尾。通过比较两个指针所指向的元素的绝对值的大小来确定哪个元素的平方应该放在结果数组的末尾。具体实现代码如下: ```python def sortedSquares(self, nums: List[int]) -> List[int]: left = 0 right = len(nums) - 1 ans = [] while left <= right: if abs(nums[left]) >= abs(nums[right]): ans.append(nums[left ** 2) left += 1 else: ans.append(nums[right ** 2) right -= 1 return ans[::-1] ``` 最后是Leetcode 209题,题目要求在给定的数组中找到长度最小的子数组,

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值