0
点赞
收藏
分享

微信扫一扫

python数据结构第六天(栈、队练习进阶)

一、栈的进阶:

1、最小栈:

《LeetCode 155. 最小栈》

题目:

在这里插入图片描述

示例:

输入:
["MinStack","push","push","push","getMin","pop","top","getMin"]
[[],[-2],[0],[-3],[],[],[],[]]

输出:
[null,null,null,null,-3,null,0,-2]

解释:
MinStack minStack = new MinStack();
minStack.push(-2);
minStack.push(0);
minStack.push(-3);
minStack.getMin();   --> 返回 -3.
minStack.pop();
minStack.top();      --> 返回 0.
minStack.getMin();   --> 返回 -2.

代码框架:

class MinStack:

    def __init__(self):


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


    def pop(self) -> None:


    def top(self) -> int:


    def getMin(self) -> int:



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

思路:

  • push()方法: 每当push()新值进来时,如果 小于等于 min_stack栈顶值,则一起push()到min_stack,即更新了栈顶最小值;
  • pop()方法: 判断将pop()出去的元素值是否是min_stack栈顶元素值(即最小值),如果是则将min_stack栈顶元素一起pop(),这样可以保证min_stack栈顶元素始终是stack中的最小值。
  • getMin()方法: 返回min_stack栈顶即可。
  • min_stack作用分析:

min_stack等价于遍历stack所有元素,把升序的数字都删除掉,留下一个从栈底到栈顶降序的栈。
相当于给stack中的降序元素做了标记,每当pop()这些降序元素,min_stack会将相应的栈顶元素pop()出去,保证其栈顶元素始终是stack中的最小元素。

实现代码:

class MinStack:
    def __init__(self):
        self.stack = []
        self.min_stack = [math.inf]

    def push(self, x: int) -> None:
        self.stack.append(x)
        self.min_stack.append(min(x, self.min_stack[-1]))

    def pop(self) -> None:
        self.stack.pop()
        self.min_stack.pop()

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

    def getMin(self) -> int:
        return self.min_stack[-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()

2、用栈实现队列:

《LeetCode 232. 用栈实现队列》

题目:

在这里插入图片描述

示例:

输入:
["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

代码框架:

class MyQueue:

    def __init__(self):


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


    def pop(self) -> int:


    def peek(self) -> int:


    def empty(self) -> bool:



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

思路:

实现代码:

class MyQueue(object):

    def __init__(self):
        self.stack1 = []
        self.stack2 = []

    def push(self, x):
        self.stack1.append(x)

    def pop(self):
        if not self.stack2:
            while self.stack1:
                self.stack2.append(self.stack1.pop())
        return self.stack2.pop()

    def peek(self):
        if not self.stack2:
            while self.stack1:
                self.stack2.append(self.stack1.pop())
        return self.stack2[-1]

    def empty(self):
        return not self.stack1 and not self.stack2

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

3、直方图最大矩形:

《LeetCode 84. 柱状图中最大的矩形》

题目:

在这里插入图片描述

示例:

在这里插入图片描述
在这里插入图片描述

代码框架:

class Solution:
    def largestRectangleArea(self, heights: List[int]) -> int:

思路:

首先,要想找到第 i 位置最大面积是什么?

是以i 为中心,向左找第一个小于 heights[i] 的位置 left_i;向右找第一个小于于 heights[i] 的位置 right_i,即最大面积为 heights[i] * (right_i - left_i -1),如下图所示:
在这里插入图片描述
所以,我们的问题就变成如何找 right_ileft_i

最简单的思路就是,就是暴力法,直接分别在 i 左右移动。

实现代码:

class Solution:
    def largestRectangleArea(self, heights: List[int]) -> int:
        stack = []
        heights = [0] + heights + [0]
        res = 0
        for i in range(len(heights)):
            #print(stack)
            while stack and heights[stack[-1]] > heights[i]:
                tmp = stack.pop()
                res = max(res, (i - stack[-1] - 1) * heights[tmp])
            stack.append(i)
        return res

二、队列进阶:

1、辅助队列:

《LeetCode 225. 用队列实现栈》

题目:

在这里插入图片描述

示例:

输入:
["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

代码框架:

输入:
["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

思路:

实现代码:

from collections import deque
class MyStack:
    def __init__(self):
        """
        Initialize your data structure here.
        """
        self.data = deque()
        self.help = deque()
    def push(self, x: int) -> None:
        """
        Push element x onto stack.
        """
        self.data.append(x)
    def pop(self) -> int:
        """
        Removes the element on top of the stack and returns that element.
        """
        while len(self.data) > 1:
            self.help.append(self.data.popleft())
        tmp = self.data.popleft()        
        self.help,self.data = self.data,self.help
        return tmp
    def top(self) -> int:
        """
        Get the top element.
        """
        while len(self.data) != 1:
            self.help.append(self.data.popleft())
        tmp = self.data.popleft()
        self.help.append(tmp)
        self.help,self.data = self.data,self.help
        return tmp
    def empty(self) -> bool:
        """
        Returns whether the stack is empty.
        """
        return not bool(self.data)

2、单调队列:

《LeetCode 1696. 跳跃游戏 VI》

题目:

在这里插入图片描述

示例:

在这里插入图片描述

代码框架:

class Solution:
    def maxResult(self, nums: List[int], k: int) -> int:

思路:

实现代码:

class Solution:
    def maxResult(self, nums: List[int], k: int) -> int:
        q = collections.deque()
        for i,num in enumerate(nums):
            while q and q[0][1]+k<i:
                q.popleft()
            cur = q[0][0]+num if q else num    
            while q and cur>q[-1][0]:
                q.pop()
            q.append((cur,i))
        return q[-1][0]
举报

相关推荐

0 条评论