给定一个NxN二进制矩阵(仅包含0或1),我们如何才能找到包含全0的最大矩形?
例:
I
0 0 0 0 1 0
0 0 1 0 0 1
II->0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 <--IV 0 0 1 0 0 0 IV 对于上面的示例,它是6×6二进制矩阵。在这种情况下,返回值将为Cell 1:(2,1)和Cell 2:(4,4)。生成的子矩阵可以是正方形或矩形。返回值也可以是所有0的最大子矩阵的大小,在此示例中为3×4。 问题来源于stack overflow
[算法]通过迭代从上到下的行来工作,对于解决该问题的每一行,其中“直方图”中的“条”由从当前行开始的所有零连续向上的零尾组成(一列的高度为0 (如果当前行中有1)。
输入矩阵mat可以是任意可迭代的,例如文件或网络流。一次只需要一行。
#!/usr/bin/env python from collections import namedtuple from operator import mul
Info = namedtuple('Info', 'start height')
def max_size(mat, value=0): """Find height, width of the largest rectangle containing all value
's.""" it = iter(mat) hist = [(el==value) for el in next(it, [])] max_size = max_rectangle_size(hist) for row in it: hist = [(1+h) if el == value else 0 for h, el in zip(hist, row)] max_size = max(max_size, max_rectangle_size(hist), key=area) return max_size
def max_rectangle_size(histogram): """Find height, width of the largest rectangle that fits entirely under the histogram. """ stack = [] top = lambda: stack[-1] max_size = (0, 0) # height, width of the largest rectangle pos = 0 # current position in the histogram for pos, height in enumerate(histogram): start = pos # position where rectangle starts while True: if not stack or height > top().height: stack.append(Info(start, height)) # push elif stack and height < top().height: max_size = max(max_size, (top().height, (pos - top().start)), key=area) start, _ = stack.pop() continue break # height == top().height goes here
pos += 1
for start, height in stack:
max_size = max(max_size, (height, (pos - start)), key=area)
return max_size
def area(size): return reduce(mul, size) 解为O(N),其中N是矩阵中元素的数量。它需要O(ncols)额外的内存,这里ncols是矩阵中的列数。
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。