剑指offer整理(附python代码)——堆栈、队列

1.用两个栈实现队列

问题描述

用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型。

考察点:栈、队列的性质

思路

  • 用两个先进后出,实现先进先出。(入队,出队)
  • “出队”:当S2不空,则对S2做弹出;若S2为空,则把S1中所有元素,逐个压入S2,最后对S2做弹出。
  • “入队:当S2空,直接对S1添加;当S2不空,也没关系,因为总会先将S2中弹空,才对S2执行压入,所以不会乱序。
class Solution1:
    def __init__(self):
        self.s1 = []
        self.s2 = []
    def push(self, node):
        #入队,跟S2状态无关
        self.s1.append(node)
    def pop(self):
        # 出队,要分S2空与否;
        #S2空,将S1中所有元素弹出到S2,再对S2弹出一个。
        if self.s2 == []:
            while self.s1:
                self.s2.append(self.s1.pop())
            return self.s2.pop()
        # 当S2不空,直接对S2弹出
        return self.s2.pop()
if __name__ == '__main__':
    s = Solution1()
    s.push([1,2,3])
    print s.pop()
[1, 2, 3]

2.包含min函数的栈

问题描述

定义栈的数据结构,请在该类型中实现一个能够得到栈最小元素的min函数

考察点

  1. 最初可能想用‘变量’保存最小元素,但是弹出最小后,次小没办法获取
  2. 引入辅助栈

测试用例

  1. 压入的比最小的大/小
  2. 弹出的是/否为当前最小值

思路

  1. 压入时,另外用辅助栈存储当前的最小值
  2. 弹出时,若弹出的为最小,则同时弹出两个栈;否则,只弹出数据栈;
class Solution2:
    def __init__(self):
        self.stack = []
        self.minstack = []
    def push(self, node):
        # write code here
        self.stack.append(node)
        if len(self.minstack)==0 or node<=self.minstack[-1]:
            self.minstack.append(node)
    def pop(self):
        # write code here
        if self.stack[-1]==self.minstack[-1]:
            self.minstack.pop(-1)
        self.stack.pop(-1)
    def top(self):
        # write code here
        return self.stack[-1]
    def min(self):
        # write code here
        return self.minstack[-1]
if __name__ == '__main__':
    s = Solution2()
    s.push([3])
    print s.min()
    s.push([4])
    print s.min()  
    s.push([2])
    print s.min()
[3]
[3]
[2]

3.栈的压入、弹出序列

问题描述

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

测试用例

  1. 两个空指针
  2. 是/非弹出序列

思路

引入辅助栈存储当前序列,弹出时分两种情况
1. 弹出元素为辅助栈栈顶:直接弹出
2. 弹出元素非辅助栈栈顶:将未入栈元素入栈,直到找到要弹出的元素;否则为‘非弹出序列’

# -*- coding:utf-8 -*-
class Solution:
    def IsPopOrder(self, pushV, popV):
        # write code here
        if not pushV or len(pushV)!= len(popV):
            return False
        stack = []
        for i in pushV:
            stack.append(i)
            while len(stack) and stack[-1] == popV[0]:
                stack.pop() # 弹出最后一个
                popV.pop(0) # 弹出第一个
        if len(stack):
            return False
        return True
if __name__ == '__main__':
    s = Solution()
    print s.IsPopOrder([1,2,3,4,5],[4,3,5,1,2])
False

猜你喜欢

转载自blog.csdn.net/jinfeixibi123456789/article/details/81042179
今日推荐