任务非常简单。
给定一个图像,一个数组,让它是整数,大小为 m x n。我们想通过一个 k x l 的窗口来遍历它,并在每个窗口中计算最小值(然后将这个最小值写在某个地方,但这不适用于算法)。
额头中的算法将给出复杂度 O (mnkl)。
您可以应用具有最小堆(堆)的算法,然后渐近线将下降到 O (log (kl) n (mk + l)) (也许我错了,但我是这样做的)。
带有堆的算法看起来像这样:向右或向左走一步,我们将新到达的数字添加到堆中(k 或 l 个添加,每个 log (kl)),并删除相同的数量(列或行,时间与添加时间相同)。
为了支持删除,堆需要巧妙地实现,通过一个代理对象,除了数字本身,它还包含它在堆中的位置的索引,堆将更新这些索引,并通过它们执行删除请求(实际上,这是一个标准技巧,如果我们通过堆实现滚动 k 统计量,我不知道不使用代理的算法)。
对于一维数组的情况,移动最小值也可以使用队列以线性时间计算。对于二维情况,我无法概括此解决方案。
我认为的方向是多么真实。也许我错过了一些明显的算法,而我正坐着,从头开始发明复杂性。堆算法有多合适?会不会因为代理的开销,我们会花费这么多时间,以至于天真的实现会更快?
好吧,也许有一种比一堆算法更快的方法?类推一维情况。
你是对的,2D 案例的算法可以从带有双端队列的 1D 案例中推导出来。
首先,遍历每一行,得到给定宽度的水平窗口的移动最小值的二维数组。
然后我们遍历结果数组的每一列,得到给定高度的垂直窗口的二维最小值数组
这是从此处获取具有 4x3 窗口的单元格 (1,1) 的结果的步骤示例
这是方形窗口(方法)的Java代码(最小/最大图像过滤器部分)
filterByBoxPattern