剑指offer【学习笔记】---栈与队列(python)

这篇博客介绍了如何使用两个栈实现队列,以及创建一个支持O(1)时间复杂度获取最小元素的栈。在队列实现中,通过在stack1中插入元素,然后转移至stack2再回填到stack1来达到在队列尾部插入的目的。删除队首元素只需直接从stack1中弹出。在最小栈中,stack1存储所有元素,stack2保存stack1中非严格降序的元素,使得min()操作只需返回stack2的栈顶元素。
摘要由CSDN通过智能技术生成

基本概念:

什么是栈

栈是一种特殊的线性表,其差别是,栈只允许在固定一端进行插入和删除数据元素操作。允许进行插入和删除数据元素的一端称为栈顶,另一端称为栈底。
在这里插入图片描述根据堆栈定义,每次进栈和出栈都在同一端。每次进栈的数据元素都放在原当前栈顶元素之前,成为新的栈顶元素;每次退栈的数据元素都是当前栈顶元素。因此,每次最后进入的数据元素,都会最先退出,被称之为后进先出表。

栈的本质

栈的功能实际上是从某种数据元素序列到另一种数据元素序列的转换。

队列

队列也是一种特殊的线性表,其差别是:队列只允许在其一端进行插入操作,在其另一端进行删除操作,允许插入操作的一端称为队尾,允许进行删除操作的一端称为队头。
根据队列的定义,每次入列的数据元素都放在原来的队尾数据元素之后成为新的队尾元素,每次出列的数据元素都是原来的队头元素。这样,最先入列的数据元素总是先出队列,所以队列是一种先进先出的线性表简称先进先出表。
在这里插入图片描述

题目一:用两个栈实现队列

用两个栈实现一个队列。队列的声明如下,请实现它的两个函数 appendTail 和 deleteHead ,分别完成在队列尾部插入整数和在队列头部删除整数的功能。(若队列中没有元素,deleteHead 操作返回 -1 )

来源:力扣(LeetCode)

想要在队列尾部插入整数可以在一个栈中实现,但是要在头部删除整数,就需要另外一个栈来辅助操作。

解题思路:

要想将新加入的元素出现栈底,将stack1视为队列
在队列尾部插入整数: 将stack1中的队列转移到stack2,在stack1中让入新元素入栈,最后让stack2中的元素回到stack1中,插入成功。
在队列头部删除整数:直接在stack1中删除头部元素即可,如果队列为空则返回-1

解题思路:

算法实现:

class CQueue:

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

    def appendTail(self, value: int) -> None:
        while self.stack1:
            self.stack2.append(self.stack1.pop())
        # add value
        self.stack1.append(value)
        # 1 <- 2
        while self.stack2:
            self.stack1.append(self.stack2.pop())
        return self.stack1


    def deleteHead(self) -> int:
        if not self.stack1: return -1
        return self.stack1.pop()

题目二:包含min函数的栈

定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的 min 函数在该栈中,调用 min、push 及 pop 的时间复杂度都是 O(1)。

来源:力扣(LeetCode)

本题难点在于让时间复杂度都为1

解题思路:

我们准备了两个栈,数据栈stack1用于存储所有元素,数据栈stack2用于存储栈stack2所有非严格降序的元素,则栈stack1中的最小元素永远都是stack2的栈顶元素,所以min()函数直接输入栈b的栈顶元素。

函数设计过程:

push()函数:当stack1中加入新元素,如果stack2为空或新入元素小于stack2的栈顶元素,则在stack2加入该元素。
pop()函数:确保stack1,stack2中元素的一致性。
top()函数:直接返回stack1的栈顶元素
min()函数:返回stack2的栈顶元素,即stack1中的最小元素

算法实现:

class MinStack:

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

    def push(self, x: int) -> None:
        self.stack1.append(x)
        if not self.stack2 or self.stack2[-1] >= x:
            self.stack2.append(x)

    def pop(self) -> None:
        if self.stack1.pop() == self.stack2[-1]:
            self.stack2.pop()

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


    def min(self) -> int:
        return self.stack2[-1]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值