algorithm - Find largest rectangle containing only zeros in an N×N binary matrix -


given nxn binary matrix (containing 0's or 1's), how can go finding largest rectangle containing 0's?

example:

          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  

for above example, 6×6 binary matrix. return value in case cell 1:(2, 1) , cell 2:(4, 4). resulting sub-matrix can square or rectangular. return value can size of largest sub-matrix of 0's, in example 3 × 4.

here's solution based on "largest rectangle in histogram" problem suggested @j_random_hacker in comments:

[algorithm] works iterating through rows top bottom, each row solving this problem, "bars" in "histogram" consist of unbroken upward trails of zeros start @ current row (a column has height 0 if has 1 in current row).

the input matrix mat may arbitrary iterable e.g., file or network stream. 1 row required available @ time.

#!/usr/bin/env python collections import namedtuple operator import mul  info = namedtuple('info', 'start height')  def max_size(mat, value=0):     """find height, width of largest rectangle containing `value`'s."""     = iter(mat)     hist = [(el==value) el in next(it, [])]     max_size = max_rectangle_size(hist)     row in it:         hist = [(1+h) if el == value else 0 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 largest rectangle fits entirely under     histogram.     """     stack = []     top = lambda: stack[-1]     max_size = (0, 0) # height, width of largest rectangle     pos = 0 # current position in histogram     pos, height in enumerate(histogram):         start = pos # position rectangle starts         while true:             if not stack or height > top().height:                 stack.append(info(start, height)) # push             elif stack , 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     start, height in stack:         max_size = max(max_size, (height, (pos - start)), key=area)         return max_size  def area(size):     return reduce(mul, size) 

the solution o(n), n number of elements in matrix. requires o(ncols) additional memory, ncols number of columns in matrix.

latest version tests @ https://gist.github.com/776423


Comments

Popular posts from this blog

javascript - Clear button on addentry page doesn't work -

c# - Selenium Authentication Popup preventing driver close or quit -

tensorflow when input_data MNIST_data , zlib.error: Error -3 while decompressing: invalid block type -