python实现《剑指offer》之栈和队列-滑动窗口的最大值

1.题目

滑动窗口的最大值

2.描述

给定一个数组和滑动窗口的大小,找出所有滑动窗口里数值的最大值。例如,如果输入数组{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]}。

3.解题思路

1.滑动窗口和最大值应当是队列。
2.先根据读取的滑动窗口大小,找出指定数组中的各个滑动窗口内的数据。然后返回其中数据的最大值。
3.考虑窗口大小的边界值,即size为0的情况。

python实现

  • 两个数组辅助空间(window-2D、maxium-1D)
class Solution:
    def maxInWindows(self, num, size):
        window = []
        maxium = []
        if size==0:
            return []
        for i in range(len(num)-size+1):
            window.append([])
            for j in (num[i : i+size]):
                window[i].append(j)
            maxium.append(max(window[i]))
        return(maxium)

先把每个窗口的数据存入window,然后求每个窗口的最大值。可追溯每个滑动窗口的数据及对应的最大值。

  • 两个数组辅助空间(window-1D、maxium-1D)
class Solution:
    def maxInWindows(self, num, size):
        maxium = []
        if size == 0:
            return []
        for i in range(len(num)-size+1):
            window = []
            for j in (num[i : i+size]):
                window.append(j)
            maxium.append(max(window))
        return(maxium)

每更新一次窗口清一次window,可追溯最后一个窗口数据和每个滑动窗口的最大值。

  • 一个数组辅助空间(maxium-1D)
class Solution:
    def maxInWindows(self, num, size):
        maxium = []
        if size == 0:
            return []
        for i in range(len(num)-size+1):
            maxium.append(max(num[i:i+size]))
        return(maxium)

不可追溯所有窗口数据,只可追溯最大值,但从基本功能实现的角度是最节省内存空间的方法。

  • 使用栈的push、pop、empty、top四种操作实现队列操作,基于冒泡排序求队列最大值。
class Stack:
    def __init__(self):
        self.stack = []
        self.maxstack = []                 #最大值栈
    def push(self, x):
        self.stack.append(x)               #栈空或x大于栈顶
        if not self.maxstack or self.maxstack[-1] <= x: 
            self.maxstack.append(x)        #入最大值栈
    def pop(self):
        topone = self.stack.pop()          #出栈元素等于最大值栈顶元素
        if topone == self.maxstack[-1]:      
            self.maxstack.pop()            #出最大值栈
    def empty(self):
        return not self.stack              #判断栈空
    def top(self):
        return self.stack[-1]              #取栈顶
    def max(self):
        return self.maxstack[-1]           #取最大值栈顶

class Queue:
    def __init__(self):
        self.stack1 = Stack()              #作入列
        self.stack2 = Stack()              #将stack1倒序后作出列
    def enqueue(self, x):                  #入列
        self.stack1.push(x)                                       
    def dequeue(self):                     #出列 
        if self.stack2.empty():                                   
            while not self.stack1.empty():  #直到stack1出栈到空
                one = self.stack1.top()     #stack1取栈顶
                self.stack1.pop()           #stack1当前栈顶出栈
                self.stack2.push(one)  #stack1当前栈顶,入栈到stack2
        #ret = self.stack2.top() 
        self.stack2.pop()                   #stack2出栈
    def getmax(self):
        tmax = 0
        if not self.stack1.empty():         #入队列状态时
            tmax = self.stack1.max()
        if not self.stack2.empty():         #出队列状态时
            tmax = max(self.stack2.max(), tmax)
        return tmax

class Solution:
    def maxInWindows(num, size):
        queue = Queue()
        maxlist = []
        if len(num) < size or size == 0:
            return maxlist
        for i in range(size):
            queue.enqueue(num[i])
        maxlist.append(queue.getmax())
        for i in range(size, len(num)):
            queue.dequeue()
            queue.enqueue(num[i])
            maxlist.append(queue.getmax())
        return maxlist

用两个栈实现入队列和出队列操作,利用冒泡排序求目标栈的最大值,并存入最大值栈,如果目标栈出栈元素等于最大值栈顶,则将最大值栈顶元素出栈。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值