LeetCode 题集:栈和队列

本文介绍 LeetCode 题集中,有关栈和队列的问题。


232. Implement Queue using Stacks(用栈实现队列)


问题描述

LeetCode 232 问题描述 I
LeetCode 232 问题描述 II

思路与代码


初始化两个栈,一个命名为 old,另一个命名为 new。具体操作如下:

  • 当新增元素时,直接压入 new 中;
  • 当弹出(输出并弹出)或输出(只输出不弹出)元素时,先判断 old 是否为空,如空,先将 new 中元素逐个压入(以栈的方式)new,再弹出(或输出)old 中最后压入的元素,否则直接弹出(或输出)

代码如下:

class MyQueue:

    def __init__(self):
        self.list_stack_old = []
        self.list_stack_new = []

    def push(self, x: int) -> None:
        self.list_stack_new.append(x)  # only need to stock a new value

    def pop(self) -> int:
        if not self.list_stack_old:
            while self.list_stack_new:
                self.list_stack_old.append(self.list_stack_new.pop())

        return self.list_stack_old.pop()  # return the first value and remove it

    def peek(self) -> int:
        if not self.list_stack_old:
            while self.list_stack_new:
                self.list_stack_old.append(self.list_stack_new.pop())

        return self.list_stack_old[-1]  # return the first value but not remove

    def empty(self) -> bool:
        return not self.list_stack_new and not self.list_stack_old


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

运行效果:
LeetCode 232 运行效果


225. Implement Stack using Queues(用队列实现栈)


问题描述

LeetCode 225 问题描述 I
LeetCode 225 问题描述 II

思路与代码


笔者采用的是两个队列实现的方式,要点如下:

  • 始终保持一个队列为空,另一个非空
  • 新增元素时,先将新元素加入空队列,再将另一个队列逐个(以队列的方式)弹出加入该队列,自身随之清空
  • 弹出(或输出)元素时,(以队列的方式)弹出非空队列的第一个元素

代码如下:

class MyStack:

    def __init__(self):
        self.list_queue_1 = []
        self.list_queue_2 = []

    def push(self, x: int) -> None:
        if not self.list_queue_1:
            self.list_queue_1.append(x)
            self.list_queue_1 += self.list_queue_2
            self.list_queue_2 = []
        else:
            self.list_queue_2.append(x)
            self.list_queue_2 += self.list_queue_1
            self.list_queue_1 = []

    def pop(self) -> int:
        if not self.list_queue_1:
            out = self.list_queue_2[0]
            self.list_queue_2 = self.list_queue_2[1:]
            return out
        else:
            out = self.list_queue_1[0]
            self.list_queue_1 = self.list_queue_1[1:]
            return out

    def top(self) -> int:
        if not self.list_queue_1:
            return self.list_queue_2[0]
        else:
            return self.list_queue_1[0]

    def empty(self) -> bool:
        return not self.list_queue_1 and not self.list_queue_2


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

运行效果:
LeetCode 225 运行效果 1

参考官方题解,笔者发现 Python 里面自带队列的方法,代码如下:

class MyStack:

    def __init__(self):
        """
        Initialize your data structure here.
        """
        self.queue1 = collections.deque()
        self.queue2 = collections.deque()


    def push(self, x: int) -> None:
        """
        Push element x onto stack.
        """
        self.queue2.append(x)
        while self.queue1:
            self.queue2.append(self.queue1.popleft())
        self.queue1, self.queue2 = self.queue2, self.queue1


    def pop(self) -> int:
        """
        Removes the element on top of the stack and returns that element.
        """
        return self.queue1.popleft()


    def top(self) -> int:
        """
        Get the top element.
        """
        return self.queue1[0]


    def empty(self) -> bool:
        """
        Returns whether the stack is empty.
        """
        return not self.queue1


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

运行效果:
LeetCode 225 运行效果 2

在官方题解中,有提供 Follow-up 的解决办法,即只使用一个队列实现栈:

LeetCode 225 官方题解

LeetCode 225 官方题解 I
LeetCode 225 官方题解 II

代码如下:

class MyStack:

    def __init__(self):
        """
        Initialize your data structure here.
        """
        self.queue = collections.deque()


    def push(self, x: int) -> None:
        """
        Push element x onto stack.
        """
        n = len(self.queue)
        self.queue.append(x)
        for _ in range(n):
            self.queue.append(self.queue.popleft())


    def pop(self) -> int:
        """
        Removes the element on top of the stack and returns that element.
        """
        return self.queue.popleft()


    def top(self) -> int:
        """
        Get the top element.
        """
        return self.queue[0]


    def empty(self) -> bool:
        """
        Returns whether the stack is empty.
        """
        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()

运行效果:
LeetCode 225 运行效果 3


150. Evaluate Reverse Polish Notation(逆波兰表达式求值)


问题描述

LeetCode 150 问题描述 I
LeetCode 150 问题描述 II

思路与代码


本题用栈的思路实现即可。

代码如下:

class Solution:
    def evalRPN(self, tokens: List[str]) -> int:
        list_stack = []
        set_opr = {'+', '-', '*', '/'}
        for c in tokens:
            if c in set_opr:
                if c == '+':
                    list_stack.append(list_stack.pop() + list_stack.pop())
                elif c == '-':
                    list_stack.append(-(list_stack.pop() - list_stack.pop()))
                elif c == '*':
                    list_stack.append(list_stack.pop() * list_stack.pop())
                else:
                    a, b = list_stack.pop(), list_stack.pop()
                    list_stack.append(int(b / a))
            else:
                list_stack.append(int(c))

        return list_stack.pop()

运行效果:
LeetCode 150 运行效果


71. Simplify Path(简化路径)


问题描述

LeetCode 问题描述 I
LeetCode 问题描述 I

思路与代码


本题通过栈来实现。

代码如下:

class Solution:
    def simplifyPath(self, path: str) -> str:
        list_stack_dir = []
        set_skip = {'..', '.', ''}  # '' means to skip '//'
        for s in path.split('/'):
            if s == '..' and list_stack_dir:  # if '..', pop to return the higher level
                list_stack_dir.pop()
            elif s not in set_skip:
                list_stack_dir.append(s)

        return '/' + '/'.join(list_stack_dir)

运行效果:
LeetCode 71 运行效果


155. Min Stack(最小栈)


问题描述

LeetCode 155 问题描述

思路与代码


如果不考虑时间复杂度为 O ( 1 ) O(1) O(1) 的要求,实现起来非常简单,代码如下:

class MinStack:

    def __init__(self):
        self.list_stack = []

    def push(self, val: int) -> None:
        self.list_stack.append(val)

    def pop(self) -> None:
        self.list_stack.pop()

    def top(self) -> int:
        return self.list_stack[-1]

    def getMin(self) -> int:
        return min(self.list_stack)


# Your MinStack object will be instantiated and called as such:
# obj = MinStack()
# obj.push(val)
# obj.pop()
# param_3 = obj.top()
# param_4 = obj.getMin()

运行效果:
LeetCode 155 运行效果 1

但如果考虑时间复杂度为 O ( 1 ) O(1) O(1) 的要求,就需要额外增加一个栈,以存储前几个元素的最小值,当弹出元素时,存储最小值的栈同样要弹出元素。

代码如下:

class MinStack:

    def __init__(self):
        self.list_stack = []
        self.list_min = []

    def push(self, val: int) -> None:
        self.list_stack.append(val)
        self.list_min.append(min(self.list_min[-1], val) if self.list_min else val)

    def pop(self) -> None:
        self.list_stack.pop()
        self.list_min.pop()

    def top(self) -> int:
        return self.list_stack[-1]

    def getMin(self) -> int:
        return self.list_min[-1]


# Your MinStack object will be instantiated and called as such:
# obj = MinStack()
# obj.push(val)
# obj.pop()
# param_3 = obj.top()
# param_4 = obj.getMin()

运行效果:
LeetCode 155 运行效果 2

显然,增加了一个栈(list),就会增加一点内存消耗。


20. Valid Parentheses(有效的括号)


问题描述

LeetCode 20 问题描述 I
LeetCode 20 问题描述 II

思路与代码


显而易见,本题也适合通过栈来实现。

代码如下:

class Solution:
    def isValid(self, s: str) -> bool:
        list_stack = []
        dict_cp = {')': '(', ']': '[', '}': '{'}
        for c in s:
            if c in dict_cp.keys():
                if not list_stack:  # in case: no left
                    return False
                elif list_stack.pop() != dict_cp[c]:  # in case: not left
                    return False

            else:
                list_stack.append(c)

        if list_stack:  # in case: no enough right
            return False
        else:
            return True

运行效果:
LeetCode 20 运行效果

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值