zoukankan      html  css  js  c++  java
  • 剑指Offer数据结构之栈和队列[Python版]

    面试题005 用两个栈实现队列

    题目表述:
    用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型。
    解题思路:
    实现入队和出队操作,stackA用来进栈,stackB出栈,stackB为空则stackA出栈给stackB
    代码:

    # -*- coding:utf-8 -*-
    class Solution:
        def __init__(self):
            self.stackA = []
            self.stackB = []
        def push(self, node):
            self.stackA.append(node)
        def pop(self):
            if not self.stackB:
                while self.stackA:
                    self.stackB.append(self.stackA.pop())
            return self.stackB.pop()
    

    面试题020 包含min函数的栈

    题目描述:定义栈的数据结构,请在该类型中实现一个能够得到栈中所含最小元素的min函数(时间复杂度应为O(1))。
    注意:保证测试中不会当栈为空的时候,对栈调用pop()或者min()或者top()方法。
    解题思路:用辅助栈存储当前data的最小值 辅助栈头即为min值
    代码

    class Solution:
        def __init__(self):
            self.stack = []
            self.assist = []
        def push(self, node):
            # write code here
            min = self.min()
            if not min or node<min:
                self.assist.append(node)
            else:
                self.assist.append(min)
            self.stack.append(node)
        def pop(self):
            # write code here
            if self.stack:
                self.assist.pop()
                return self.stack.pop()
        def top(self):
            # write code here
            if self.stack:
                return self.stack[-1]
        def min(self):
            # write code here
            if self.stack:
                return self.assist[-1]
    

    面试题021 栈的压入、弹出序列

    题目描述:输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。(注意:这两个序列的长度是相等的)
    解题思路:
    借用一个辅助的栈,遍历压栈顺序,先讲第一个放入栈中,这里是1,然后判断栈顶元素是不是出栈顺序的第一个元素,这里是4,很显然1≠4,所以我们继续压栈,直到相等以后开始出栈,出栈一个元素,则将出栈顺序向后移动一位,直到不相等,这样循环等压栈顺序遍历完成,如果辅助栈还不为空,说明弹出序列不是该栈的弹出顺序。
    举例:
    入栈1,2,3,4,5
    出栈4,5,3,2,1
    首先1入辅助栈,此时栈顶1≠4,继续入栈2
    此时栈顶2≠4,继续入栈3
    此时栈顶3≠4,继续入栈4
    此时栈顶4=4,出栈4,弹出序列向后一位,此时为5,,辅助栈里面是1,2,3
    此时栈顶3≠5,继续入栈5
    此时栈顶5=5,出栈5,弹出序列向后一位,此时为3,,辅助栈里面是1,2,3
    ….
    依次执行,最后辅助栈为空。如果不为空说明弹出序列不是该栈的弹出顺序。
    代码

    class Solution:
     
        def IsPopOrder(self, pushV, popV):
            # stack中存入pushV中取出的数据
            stack=[]
            while popV:
                # 如果第一个元素相等,直接都弹出,根本不用压入stack
                if pushV and popV[0]==pushV[0]:
                    popV.pop(0)
                    pushV.pop(0)
                #如果stack的最后一个元素与popV中第一个元素相等,将两个元素都弹出
                elif stack and stack[-1]==popV[0]:
                    stack.pop()
                    popV.pop(0)
                # 如果pushV中有数据,压入stack
                elif pushV:
                    stack.append(pushV.pop(0))
                # 上面情况都不满足,直接返回false。
                else:
                    return False
            return True
    

    面试题044 翻转单词顺序列(栈)

    题目描述:牛客最近来了一个新员工Fish,每天早晨总是会拿着一本英文杂志,写些句子在本子上。同事Cat对Fish写的内容颇感兴趣,有一天他向Fish借来翻看,但却读不懂它的意思。例如,“student. a am I”。后来才意识到,这家伙原来把句子单词的顺序翻转了,正确的句子应该是“I am a student.”。Cat对一一的翻转这些单词顺序可不在行,你能帮助他么?
    解题思路:通过空格隔开,然后用栈存储,最后弹出
    代码

    class Solution:
        def ReverseSentence(self, s):
            # write code here
            stack = [n for n in s.split(' ')]
            stack.reverse()
            return ' '.join(stack)
    

    面试题064 滑动窗口的最大值(双端队列)

    题目描述:给定一个数组和滑动窗口的大小,找出所有滑动窗口里数值的最大值。例如,如果输入数组{2,3,4,2,6,2,5,1}及滑动窗口的大小3,那么一共存在6个滑动窗口,他们的最大值分别为{4,4,6,6,6,5}; 针对数组{2,3,4,2,6,2,5,1}的滑动窗口有以下6个: {[2,3,4],2,6,2,5,1}, {2,[3,4,2],6,2,5,1}, {2,3,[4,2,6],2,5,1}, {2,3,4,[2,6,2],5,1}, {2,3,4,2,[6,2,5],1}, {2,3,4,2,6,[2,5,1]}。
    解题思路:直接找滑动窗口范围内的最大值
    代码

    class Solution:
        def maxInWindows(self, num, size):
            # write code here
            if size <= 0:
                return []
            res = []
            for i in xrange(0, len(num)-size+1):
                res.append(max(num[i:i+size]))
            return res
    

    解题思路:滑动窗口用队列保存,遇到以下情况处理:窗口第一个槽始终是最大值 窗口第一个槽过期要丢弃 窗口从尾比到头丢弃最小的数
    代码

    class Solution:
        def maxInWindows(self, num, size):
            # write code here
            if size == 0:
                return []
            queue = []
            res = []
            for i in range(len(num)):
                while queue and queue[0] <= i-size:
                    queue.pop(0)
                while queue and num[queue[-1]] < num[i]:
                    queue.pop(-1)
                queue.append(i)
                if i<size-1:
                    continue
                res.append(num[queue[0]])
            return res
    
  • 相关阅读:
    安装IDM扩展
    Go_数组&切片
    Mycat概念&安装
    IDEA自定义主题
    完全卸载Oracle11g
    创建型模式——单例模式(Singleton)
    设计模式统计
    PHP解压带密码的zip文件
    Win推荐软件
    如何设置线程池的线程数?
  • 原文地址:https://www.cnblogs.com/eugene0/p/12860457.html
Copyright © 2011-2022 走看看