1. 程式人生 > 其它 >卷積滑動視窗python程式碼_Python —— 滑動視窗最小值

卷積滑動視窗python程式碼_Python —— 滑動視窗最小值

技術標籤:卷積滑動視窗python程式碼

考慮一個經常碰到的問題,對於一個數組,現在有一個視窗[i, j]ij只會做增加的操作,要求輸出[i,j]上的最小值。

這其實就是一個“最小佇列(min queue)”問題:維護一個佇列,使得插入、彈出、獲取最小值這三個操作的平均時間複雜度都是

equation?tex=O%281%29

實現這個的方法是使用兩個佇列,其中一個是單調佇列。

思路參見:

滑動視窗的最小值問題_C/C++_weixin_38391092的部落格-CSDN部落格​blog.csdn.net f7aace991fe6a95783f5e3feaba5ffc6.png
import collections

class MinQueue(collections.deque):
    
    def __init__(self, iterable=None, maxlen=None):
        super().__init__(maxlen=maxlen)
        self.minQueue = collections.deque()
        if isinstance(iterable, collections.abc.Iterable):
            for it in iterable:
                self.append(it)
    
    @property
    def minV(self):
        return self.minQueue[0] if self.minQueue else None
    
    def append(self, v):
        while self.minQueue and v < self.minQueue[-1]:
            self.minQueue.pop()
        self.minQueue.append(v)
        super().append(v)
    
    def extend(self, iterable):
        for it in iterable:
            self.append(it)
    
    def pop(self):
        if not self.minQueue:
            return None
        v = super().popleft()
        if self.minQueue[0] == v:
            self.minQueue.popleft()
        return v

上面用 python 對這一問題做了很好的封裝。

同樣的,有滑動視窗最大值

import collections

class MaxQueue(collections.deque):
    
    def __init__(self, iterable=None, maxlen=None):
        super().__init__(maxlen=maxlen)
        self.maxQueue = collections.deque()
        if isinstance(iterable, collections.abc.Iterable):
            for it in iterable:
                self.append(it)
    
    @property
    def maxV(self):
        return self.maxQueue[0] if self.maxQueue else None
    
    def append(self, v):
        while self.maxQueue and v > self.maxQueue[-1]:
            self.maxQueue.pop()
        self.maxQueue.append(v)
        super().append(v)
    
    def extend(self, iterable):
        for it in iterable:
            self.append(it)
    
    def pop(self):
        if not self.maxQueue:
            return None
        v = super().popleft()
        if self.maxQueue[0] == v:
            self.maxQueue.popleft()
        return v