当前位置:网站首页>leetcode 85. 最大矩形
leetcode 85. 最大矩形
2022-06-22 12:26:00 【昂昂累世士】
题目描述:
给定一个仅包含 0 和 1 、大小为 rows x cols 的二维二进制矩阵,找出只包含 1 的最大矩形,并返回其面积。
示例 1:
输入:matrix = [[“1”,“0”,“1”,“0”,“0”],[“1”,“0”,“1”,“1”,“1”],[“1”,“1”,“1”,“1”,“1”],[“1”,“0”,“0”,“1”,“0”]]
输出:6
解释:最大矩形如上图所示。
示例 2:
输入:matrix = []
输出:0
示例 3:
输入:matrix = [[“0”]]
输出:0
示例 4:
输入:matrix = [[“1”]]
输出:1
示例 5:
输入:matrix = [[“0”,“0”]]
输出:0
提示:
rows == matrix.length
cols == matrix[0].length
1 <= row, cols <= 200
matrix[i][j] 为 ‘0’ 或 ‘1’
分析
很有意思的一道题,本题相当于leetcode 84. 柱状图中最大的矩形这题的拓展应用。
首先我们要求矩阵中全为1的子矩阵中最大矩形的面积。暴力做法是枚举矩形的左上角和右下角坐标来确定一个矩形,时间复杂度是O(n4),至于判断这个矩形里是不是全1,使用二维前缀和就可以在O(1)的时间内判断出来。显然暴力的做法会TLE,n的规模是200,如果我们能将复杂度降低到立方级别,就可以解决本题了。既然枚举矩形的两个顶点会超时,那么我们优化的方向就可以是只去枚举一个顶点,这和在线性DP里面我们往往只需要求以某个元素为末尾的最优解,而不用去枚举左右端点来求最优解一样。因此本题我们可以只去枚举矩形的右下角顶点,用f[i][j]表示以第i行第j列元素为矩形的右下角的矩形中最大的面积。
随便举个例子:
0 1 1 1 1
0 1 0 1 1
1 1 1 1 1
我们以上面矩阵的右下角端点为矩形的右下角端点,尝试来枚举能够构成的矩形的宽度,可以发现最后一行有5个连续的1,但是并不能延伸到倒数第二行,因此宽度为5的矩形最大面积就是5,。再来增加矩形的高度,向上枚举,由于第二行最右边只有两个连续的1,所以最后一行只有两个1能继续往上延伸,新的宽度就是2,一直可以延伸到第一行,这样宽度是2的矩形的最大面积就是2 * 3 等于6了。
观察下上面的枚举过程,可以发现,在枚举以matrix[i][j]为矩形右下角的矩形时,宽度能够向左延伸到多少取决于matrix[i][j]左边有多少个连续的1,而向上增加矩形的高度时,能够向上继续延伸的宽度取决左边1最少的那一行,比如最后一层有5个1,由于第二层最右边只有2个1,矩形的宽度就不得不缩减到2,再往上如果最后一列左边的1继续减少的话,矩形的宽度还会继续减少,这其中一直要使用的一个属性就是矩形中某个元素及其左边有多少个1.
如果预处理出来w[i][j]为matrix[i][j]及在第i行第j列左边连续1的个数,则状态转移方程为w[i][j] = w[i][j-1] + 1,matrix[i][j] = 1时;w[i][j] = 0,matrix[i][j] = 0时。有了w[i][j]这个属性,我们枚举以matrix[i][j]为右下顶点的矩形时,就只需要向上去枚举矩形的高度了,因为宽度为已经枚举行的w的最小值。这样整体算法的复杂度就降低到了立方级别。
观察上图,我们之前的算法在枚举最后一列时,以第三行最后一列为矩形右下顶点的最大矩形面积等于max(5,2*3);以第二行最后一列为右下顶点的最大矩形面积等于2 * 2;以第一行最后一列为右下顶点的最大矩形面积等于4。这一列为右下角能够构成的矩形的最大面积恰好就是上图所绘的直方图中最大矩形的面积,也就是我们求一列元素构成矩形右下角的矩形中最大的面积时,就只需要求以这列元素为横坐标,其左边1的个数为纵坐标的直方图中矩形的最大面积,也就是开头所说的那题一模一样的问题,使用单调栈就可以将一列最大矩形的面积的枚举时间复杂度优化到线性,总的复杂度是平方级别的。求直方图的最大面积可以参考AcWing 131 直方图中最大的矩形这篇题解。
代码
O(n3) 模拟解法
class Solution {
public:
int w[205][205] = {
0};
int maximalRectangle(vector<vector<char>>& matrix) {
int m = matrix.size(),n = matrix[0].size();
for(int i = 0;i < m;i++){
w[i][0] = (matrix[i][0] == '1');
for(int j = 1;j < n;j++){
if(matrix[i][j] == '1') w[i][j] = w[i][j-1] + 1;
}
}
int res = 0;
for(int i = 0;i < m;i++){
for(int j = 0;j < n;j++){
int wid = w[i][j];
for(int k = i;k >= 0&&wid;k--){
wid = min(wid,w[k][j]);
res = max(res,wid*(i - k + 1));
}
}
}
return res;
}
};
O(n2) 单调栈解法
class Solution {
public:
int w[205][205] = {
0};
int maximalRectangle(vector<vector<char>>& matrix) {
int m = matrix.size(),n = matrix[0].size();
for(int i = 0;i < m;i++){
w[i][0] = (matrix[i][0] == '1');
for(int j = 1;j < n;j++){
if(matrix[i][j] == '1') w[i][j] = w[i][j-1] + 1;
}
}
int res = 0;
for(int j = 0;j < n;j++){
vector<int> stk;
vector<int> l(m+1,0);
stk.push_back(-1);
w[m][j] = -1;
for(int i = 0;i <= m;i++){
while(stk.size() > 1 && w[i][j] < w[stk.back()][j]){
int u = stk.back();
res = max(res,w[u][j]*(i - l[u] - 1));
stk.pop_back();
}
l[i] = stk.back();
stk.push_back(i);
}
}
return res;
}
};
边栏推荐
- Stop using system Currenttimemillis() takes too long to count. It's too low. Stopwatch is easy to use!
- Tis tutorial 02 model
- Tianyi cloud explores a new idea of cloud native and edge computing integration
- SAP-abap-OLE核心代码
- 这不会又是一个Go的BUG吧?
- Precautions for upgrading php8 of diyun CMS
- Difference between function pointer and pointer function
- Latex Greek alphabet
- Automatically delete the log files in the specified directory and within the specified time
- Help financial informatization innovation, Jushan database has won more than 50 financial customers recently
猜你喜欢

SAP-ABAP- 如何查找表,字段有哪些关联表

Sap-abap- how to transfer material master data, supplier master data, work orders, purchase orders and other information to external systems in real time - implicit enhancement.

在C#开发中使用第三方组件LambdaParser、DynamicExpresso、Z.Expressions,实现动态解析/求值字符串表达式

SAP fi financial statement version setting

Parallels Desktop 17.1.4pd virtual machine

SAP SPRO configure how to display the corresponding t-code

Jushan database was invited to attend Kunpeng developers' annual event 2022 to jointly build a domestic digital base

SAP 系统License查看申请及导入

MySQL_数据处理之增删改

轻松上手Fluentd,结合 Rainbond 插件市场,日志收集更快捷
随机推荐
基于can总线的A2L文件解析(1)
MySQL_数据处理之增删改
Redis
Flutter's custompaint drawing Bezier curve chart (III)
[Jishu reading] arm64 learning experience sharing by running bar community
Hurun Research Institute launched the list of potential enterprises of China's meta universe, and Jushan database was selected as the future star enterprise
Flutter版 仿.知乎列表的视差效果
[QT] qfileinfo get the components of the file name
建立自己的网站(5)
[MySQL] the difference between where and having
这不会又是一个Go的BUG吧?
Arcpy 添加图层到地图文档
Sap-abap- how to open a local file
Difference between function pointer and pointer function
Tianyi cloud digital government smart data center has passed the certification
Sap-abap- how to transfer material master data, supplier master data, work orders, purchase orders and other information to external systems in real time - implicit enhancement.
Tis tutorial 01- installation
C language itoa() function and atoi() function explanation (integer to character c implementation)
SAP-ABAP-SE14丢失的数据如何恢复
在C#开发中使用第三方组件LambdaParser、DynamicExpresso、Z.Expressions,实现动态解析/求值字符串表达式