Maximal Rectangle

Stack, Dynamic Programming, Array, Hash Table

Hard

Given a 2D binary matrix filled with 0's and 1's, find the largest rectangle containing only 1's and return its area.

Example:

Input:
[
  ["1","0","1","0","0"],
  ["1","0","1","1","1"],
  ["1","1","1","1","1"],
  ["1","0","0","1","0"]
]
Output: 6

Solution & Analysis

Via @wangyushawn's, @calis's answer

This question is similar as [Largest Rectangle in Histogram]:

You can maintain a row length of Integer array H recorded its height of '1's, and scan and update row by row to find out the largest rectangle of each row.

For each row, if matrix[row][i] == '1'. H[i] +=1, or reset the H[i] to zero. and accroding the algorithm of [Largest Rectangle in Histogram], to update the maximum area.

See also: Solution based on Maximum Rectangle in Histogram

Two Pass

by @agritsik

Dynamic Programming

Via @morrischen2008's answer:

The DP solution proceeds row by row, starting from the first row. Let the maximal rectangle area at row i and column j be computed by [right(i,j) - left(i,j)]*height(i,j).

All the 3 variables left, right, and height can be determined by the information from previous row, and also information from the current row. So it can be regarded as a DP solution. The transition equations are:

left(i,j) = max(left(i-1,j), cur_left), cur_left can be determined from the current row

right(i,j) = min(right(i-1,j), cur_right), cur_right can be determined from the current row

height(i,j) = height(i-1,j) + 1, if matrix[i][j]=='1';

height(i,j) = 0, if matrix[i][j]=='0'

-------@wahcheung--------

策略: 把matrix看成多个直方图, 每一行及其上方的数据都构成一个直方图, 需要考察matrix.size()个直方图

  • 对于每个点(row, col), 我们最后都计算以这个点上方的连续的'1'往left, right方向延申可以得到的最大的矩形的面积

  • 通过这种方法获取的矩形一定会把最大的矩形包含在内

  • height[row][col]记录的是(row, col)这个坐标为底座的直方图柱子的高度, 如果这个点是'0', 那么高度当然是0了

  • left[row][col]记录的是(row, col)这个坐标点对应的height可以延申到的最左边的位置

  • right[row][col]记录的是(row, col)这个坐标点对应的height可以延申到的最右边的位置+1

以上面的matrix为例,

  • 对于(row=2, col=1)这个点, left=0, right=5, height=1

  • 对于(row=2, col=2)这个点, left=2, right=3, height=3

  • (2,2)这个点与(2,1)紧挨着,left和right却已经变化如此之大了, 这是因为left和right除了受左右两边的'1'影响, 还受到了其上方连续的'1'的制约

  • 由于点(2,2)上有height=3个'1', 这几个'1'的left的最大值作为当前点的left, 这几个'1'的right的最小值作为当前点的right

因此, 实际上, 我们是要找以height对应的这条线段往左右两边移动(只能往全是'1'的地方移动), 可以扫过的最大面积。

当height与目标最大矩形区域的最短的height重合时, 最大矩形的面积就找到了, 如上面的例子, 就是点(2,3)或(2,4)对应的height

--

Code by @Self_Learner

Last updated

Was this helpful?