LeetCode 常见栈和队列问题 (python实现)

栈和队列

1. 用栈实现队列

LeetCode 232. Implement Queue using Stacks (Easy)

栈和队列是两种顺序完全相反的数据结构。队列先进先出(First In First Out),栈先进后出(First In Last Out)。可以通过使用两个栈,数据在两个栈之间来回“倒腾”,实现队列的功能。

class MyQueue:

    def __init__(self):
        """
        Initialize your data structure here.
        """
        self.stack1 = []
        self.stack2 = []
        

    def push(self, x: int) -> None:
        """
        Push element x to the back of queue.
        """
        while self.stack2:
            self.stack1.append(self.stack2.pop())
        self.stack1.append(x)
        while self.stack1:
            self.stack2.append(self.stack1.pop())

    def pop(self) -> int:
        """
        Removes the element from in front of queue and returns that element.
        """
        return self.stack2.pop()
        

    def peek(self) -> int:
        """
        Get the front element.
        """
        return self.stack2[-1]
        

    def empty(self) -> bool:
        """
        Returns whether the queue is empty.
        """
        if len(self.stack2) == 0:
            return True
        else:
            return 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()
2. 用队列实现栈

LeetCode 225. Implement Stack using Queues (Easy)

与上面问题实现方法相同。后来的元素进队之前,把队中的元素全部转移到另一个队中,让新来的元素先进队。然后再把数据转移回来。

class MyStack:

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

    def push(self, x: int) -> None:
        """
        Push element x onto stack.
        """
        while self.queue2:
            self.queue1.append(self.queue2[0])
            del self.queue2[0]
        self.queue2.append(x)
        while self.queue1:
            self.queue2.append(self.queue1[0])
            del self.queue1[0]
        

    def pop(self) -> int:
        """
        Removes the element on top of the stack and returns that element.
        """
        ret = self.queue2[0]
        del self.queue2[0]
        return ret
        

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

    def empty(self) -> bool:
        """
        Returns whether the stack is empty.
        """
        if len(self.queue2) == 0:
            return True
        else:
            return 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()
3. 最小值栈

LeetCode 155. Min Stack (Easy)

设置两个栈stack, miniStack,stack用来存储数据,miniStack专门用来存储当前状态的最小值。如果从栈中pop一个数据,那么同时从两个栈里面弹出数据,那么miniStack栈顶依然是当前状态的最小值。Note:如果栈回到空状态,那么min同样也需要初始化到inf的状态,因为历史已经清空了。上一次保存的min失效

class MinStack:

    def __init__(self):
        """
        initialize your data structure here.
        """
        self.stack = []
        self.miniStack = []
        self.min = float('inf')
        

    def push(self, x: int) -> None:
        self.stack.append(x)
        self.min = min(x, self.min)
        self.miniStack.append(self.min)

            
    def pop(self) -> None:
        self.stack.pop()
        self.miniStack.pop()
        # set self.min to inf when the self.miniStack is enmpy. Because when the stack is empty just like the original cases, the min is inf not the history.
        self.min = float('inf') if len(self.miniStack) == 0 else self.miniStack[-1] 
        

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

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


# 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()
4. 用栈实现括号匹配

LeetCode 20. Valid Parentheses (Easy)

定义left存储左括号,以及组合符号,和一个空栈。遍历字符串,如果当前字符是是左括号,则直接进栈。如果是右括号,那么判断栈的情况,如果是空栈直接返回False,如果不是空栈,则栈顶元素与当前符号进行匹配。如果是成对的,那么弹出栈顶字符,如果不匹配,那么返回错误值。所有字符串遍历完毕,如果栈不空,那么返回False,如果栈空返回True。

class Solution:
    def isValid(self, s: str) -> bool:
        left = ['(', '{', '[']
        combine = ['()', '{}', '[]']
        stack = []
        
        for ch in s:
            if ch in left:
                stack.append(ch)
            else:
                if len(stack) == 0: return False
                if stack[-1] + ch not in combine:
                    return False
                else:
                    stack.pop()
        if len(stack) == 0:
            return True
        else:
            return False
5. 数组中元素与下一个比它大的元素之间的距离

LeetCode 739. Daily Temperatures (Medium)

本题实现方法为单调栈。依然需要明确栈的特性**“先进后出”**是如何在本题中应用的。整个栈从栈顶到栈底数值是递增的。

遍历每日温度,若当日温度大于栈顶索引日的温度,说明当日是栈顶元素的升温日,因此将栈顶元素出栈,计算其与当日的天数差,存放与结果数组中。遍历结束,栈中剩余的元素没有升温日,保持默认值为 0

  1. 顺序遍历列表元素

  2. 每个元素下面都进行一次while循环

  3. 如果栈空,则向栈内压进一个元素;

    2.1 如果栈非空,且当前元素比栈顶元素要小,那么向栈内压入该元素(因为没有找到比当前元素大的元素,那么只能将当前元素的信息记录到栈的底面,优先计算后面的元素)

    2.2 如果栈非空,且当前元素比栈顶元素要大,那么弹出栈顶元素,并计算栈顶元素与当前元素之间的距离(索引距离)。(意味着栈顶元素已经找到比他大的第一个元素了,该元素就是当前遍历元素

  4. 遍历结束,如果栈内还有元素,那么意味着,这些元素后面的元素没有找到比他大的值。(由于初始化res为全0列表,因此可以不用考虑这些元素的值)

class Solution:
    def dailyTemperatures(self, T: List[int]) -> List[int]:
        res = [0 for _ in range(len(T))]
        stack = []
        
        for curr_index, curr_temperature in enumerate(T):
            while stack and stack[-1][1] < curr_temperature:
                top_index = stack.pop()[0]
                res[top_index] = curr_index - top_index
            stack.append((curr_index, curr_temperature))
        return res
6. 循环数组中比当前元素大的下一个元素

LeetCode 503. Next Greater Element II (Medium)

本题与上一题实质是一样的。因为最终返回的数组res大小与传入数组nums是一样的。由于nums是一个环形的,因此将其复制两倍的,同时也计算两倍长度的res,最终返回一半即可。

class Solution:
    def nextGreaterElements(self, nums: List[int]) -> List[int]:
        res = [-1 for _ in range(2 * len(nums))]
        stack = []
        new_nums = nums * 2
        
        for curr_index, curr_item in enumerate(new_nums):
            while stack and curr_item > stack[-1][1]:
                topStack = stack.pop()
                res[topStack[0]] = curr_item
            stack.append((curr_index, curr_item))
        
        return res[:len(nums)]
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值