求解最大子矩阵的大小
【题目】
给定一个整型矩阵,其中的值只有0和1两种,求其中全是1的所有矩形区域中,最大的矩形区域为1的数量。
例如:
1 1 1 0
其中,最大的矩形区域有3个1,所以返回3。再如:
1 0 1 1
1 1 1 1
1 1 1 0
其中,最大的矩形区域有6个1,所以返回6。
思路:
先计算以data[i]为底的矩阵大小,
例如:
1 0 1 1
1 1 1 1
1 1 1 0
以第一行为底,大小[1,0,1,1]
第二行为底,大小[2,1,2,2]
第三行为底,大小[3,2,3,0]
遇到0就置为0,故用 height[i] = data[i*cols+j]==0 ? 0 : height[i]+1; 如果遇到0,就置0,否则,高度+1,得到一个以data[i]为底的矩阵大小;
实际上可以看作一个直方图:例如:以第三行为底,可以得到

转化为在直方图的计算就是,以同一边作为底,当前最大能覆盖的矩阵面积:
注意,
每一个计算得到的直方图,都需要进行计算一下最大矩阵,例如用例4:

显然,第二三四五行中,得到的height矩阵,都是[0,0,0,0,0]
最大矩阵在第一行,
接下来计算最大矩阵:
例如height[]={
1,4,3,2,4,5}height[] = \{1,4,3,2,4,5\}height[]={
1,4,3,2,4,5}
定义栈stack,
- 当前栈为空,或者遇到一个比当前栈顶大的值,压栈(放入
坐标i,而不是height[i])。这样一来,栈里的坐标标注的矩阵,就都是递增的矩阵了。

例如这里的1,4,就可以直接入栈了,此时栈中是他们所在的坐标:[0,1][0,1][0,1]
-
遇到一个和当前栈顶一样大,或者比当前栈顶小的值:
if(!stack.empty() && height[i]<=height[stack.top()])if(!stack.empty()\ \ \&\& \ \ \ height[i]<=height[stack.top()])if(!stack.empty() && height[i]<=height[stack.top()])
说明矩阵大小开始收缩了,
此时以当前遍历到的j = stack.top()为中心,向左右进行扩展

此时遇到了3,j = stack.top(),所以j=1
可以计算高度为4的矩阵的最大大小了,
这里,4向左,只能遍历到坐标为1的位置,也就是它自身
4向右,只能遍历到左边为1的位置,也就是它自身
所以4所在位置的最大矩阵大小只能是4;
此时,栈中,j被弹出,再压入当前i,修改后的坐标为:[0,2][0,2][0,2] -
可知若height[i]<height[stack.top()]height[i]<height[stack.top()]hei

本文讲解了如何通过计算直方图和栈操作找到给定矩阵中全为1的最大矩形区域的大小。通过实例演示和C++代码实现,展示了寻找最大子矩阵面积的有效算法思路。
最低0.47元/天 解锁文章
1767

被折叠的 条评论
为什么被折叠?



