算法入门——数据结构(栈)python3实现(2)

 要求:

输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。

1. 0<=pushV.length == popV.length <=1000

2. -1000<=pushV[i]<=1000

3. pushV 的所有数字均不相同

示例1:

输入:

[1,2,3,4,5],[4,5,3,2,1]

返回值:

true

说明:

可以通过push(1)=>push(2)=>push(3)=>push(4)=>pop()=>push(5)=>pop()=>pop()=>pop()=>pop()
这样的顺序得到[4,5,3,2,1]这个序列,返回true 

示例2:

输入:

[1,2,3,4,5],[4,3,5,1,2]

返回值:

false

说明:

由于是[1,2,3,4,5]的压入顺序,[4,3,5,1,2]的弹出顺序,要求4,3,5必须在1,2前压入,且1,2不能弹出,但是这样压入的顺序,1又不能在2之前弹出,所以无法形成的,返回false 。

思路:

方法一:辅助栈

 首先创建一个辅助栈stack。遍历pushV,将压入栈pushV中的元素依次压入辅助栈stack中,比较辅助栈stack的栈顶元素与弹出栈popV的第一个元素是否相等,当两者相等时,停止将压入栈pushV中的元素依次压入辅助栈stack中,并弹出stack栈中的顶部元素。

接着继续往辅助栈stack中压入元素,同时继续比较辅助栈stack的栈顶元素与弹出栈popV的第二个元素是否相等,如果相等,停止压入操作,并弹出stack栈中的栈顶元素。

……

重复上述工作,直到辅助栈stack为空栈。此时popV的元素顺序就是压入栈pushV的弹出顺序。

图解:

 比较辅助栈stack的栈顶元素与弹出栈popV的第一个元素是否相等,发现有元素相等时,就停止压入,同时弹出这个栈顶元素:

 接着继续压入pushV中的元素,比较辅助栈stack的栈顶元素与弹出栈popV的第二个元素是否相等,当发现相等元素时:

 重复上述操作,直到辅助栈stack为空,且弹出栈popV的元素顺序值与popV的长度相等。

 代码实现:

def IsPopOrder(pushV, popV):
    j = 0
    stack = []  # 用列表初始化辅助栈stack
    for x in pushV:  # 把压入栈pushV中的元素依次压入辅助栈stack中
        stack.append(x)
        while stack and stack[-1] == popV[j]:
            stack.pop()
            j = j + 1
    return j == len(popV)


pushV = [1, 2, 3, 4, 5]
popV = [4, 3, 5, 2, 1]
print(IsPopOrder(pushV, popV))
# True

方法二:直接在pushV上进行操作

  • 当pushV[i] != popV[0]元素,表示还没匹配到待弹出元素;继续i = i + 1压入元素;
  • 当push[i] == popV[0]时,即匹配到待弹出元素,并i = i - 1让它始终指向pushV的顶部元素(也就相当于是弹出了栈顶元素);同时popV也要更新到下一个元素j = j + 1,使其成为新的popV[0]。最后直到pushV 和popV都为空即匹配结束。

代码实现:

def IsPopOrder(self, pushV, popV):
    i = j = 0
    for x in pushV:
        pushV[i] = x
        while i >= 0 and pushV[i] == popV[j]:  # 当pushV的当前元素等于popV弹出的顶部元素时中止循环
            i, j = i - 1, j + 1  # 分别更新栈顶的元素
        i += 1  # 否则继续往pushV中添加元素
    return i == 0  # 直到pushV的索引减小到0

pushV = [1, 2, 3, 4, 5]
popV = [4,3,5,1,2]
print(IsPopOrder(pushV, popV))
# False

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

弓早早o_O

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值