牛客网-Python-滑动窗口的最大值(双端队列)

题目描述

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

思路

对每次滑动窗口找到最大值,记录下最大值和最大值的下标。

若下标在窗口范围内,则比较新增加的值和当前最大值,若大于当前最大值则最大值和下标更改。

若下标不在窗口范围内,则再次遍历找最大值

代码

# -*- coding:utf-8 -*-
class Solution:
    def maxInWindows(self, num, size):
        # write code here
        if size == 0:
            return []
        resultList = []
        result = num[0]
        flag = 0
        for j in range(0,len(num)-size+1):
            if flag!=0 and flag>=j:
                if num[j+size-1]>=result:
                    result = num[j+size-1]
                    flag = j+size-1
            else:
                result = num[j]
                flag = j
                for i in range(1,size):
                    if result<=num[j+i]:
                        result = num[j+i]
                        flag = j+i
            resultList.append(result)
        return resultList

  

改进

用双端队列,列表的前端存放最大值的下标

窗口扩大时,做以下操作(删掉比它小的值和下标不在范围内的值,即可以保证对比了大小也可以保证顺序)

1.若末端值小于当前值,删除末端值

2.若当前下标在范围外,则删除

添加该元素

取以每次窗口最前端为下标的值

代码

# -*- coding:utf-8 -*-
class Solution:
    def maxInWindows(self, num, size):
        # write code here
        result = []
        res = []
        for i in range(0,len(num)):
            flag = i-size+1
            while(result and num[i]>=num[result[-1]]):
                del result[-1]
            while(result and result[0]<flag):
                del result[0]
            result.append(i)
            if flag>=0 and size>0:
                res.append(num[result[0]])
        return res

 

 

posted @ 2020-02-07 15:20  ditingz  阅读(457)  评论(0编辑  收藏  举报