原题如下:
给定一个仅包含 0 和 1 的二维二进制矩阵,找出只包含 1 的最大矩形,并返回其面积。
示例:
输入:
[
[“1”,“0”,“1”,“0”,“0”],
[“1”,“0”,“1”,“1”,“1”],
[“1”,“1”,“1”,“1”,“1”],
[“1”,“0”,“0”,“1”,“0”]
]
输出: 6
讲真的刚拿到这题愣是看半天无从下手,首先想到的是依次遍历各元素,为‘1’的时候 再算以此为左上顶点的最大矩形可以达到多少。但是很快这种想法很快就被扼杀在摇篮里,因为 时间复杂度简直不能直视。。。
如果给一个vector<vector> matrix 假设我们可以求出一个最大的面积,那么我们把matrix缩小一行 也是可以求出一个 最大的面积的,如果仅仅有一行呢?(肯定可以)(那么需要想一想 我们是不是可以通过第一行的最大面积 加上第二行的情况 推倒出 前两行的最大面积? ) 那么问题来了,我们需要保存哪些数据???才能帮助我们去推倒后面的最大面积,{
ps:需要注意的是 把一行一行 看成整体 然后从行开始遍历的时候 对于 其中一行 而言 哪一列出现了‘0’ 就好像“前功尽弃”了一样 (因为这会使得那一列 无效) 所以!!!我们需要 保存一下 这一列的 前面的(除他之外的)行中 (高度情况或者是说 ‘1’的情况!!!)所以 你需要开一个数组 数组的的大小就是 matrix的列的大小,但是LZ比暴力,竟然 构造了一个三维数组,(对每一个列 又开了一个二维数组 记录了 每两行的高度情况,)
}
ps: 这里说个跑题的东西 有必要说明一下!!!只用开一个一维数组 记录 高度就行了!!!( 而且 你需要注意的是 高度 是 基于上一层的高度来的 如果 当前是‘0’ 把这一列的高度 置为 0 否则 在 上一层的高度之上再加1)知道高度之后呢 宽度呢? (LZ提交之后 看了其他人的代码,很多都是用栈来解决的, 其实 两个变量 来保存 宽度的起始和终止位置就行 当遇到‘0’的时候 都给 制成 当前的列号 即可)
代码如下(别嘲笑LZ的乐色代码,没办法dp的题做的太少了,知道大致思路 但是总是做很多无用功,导致算法时间复杂度偏差很大(竟然只击败了1%!!!)):
struct node {
vector<vector<int>>m;
};
vector<vector<int>> chushihua_total(vector<vector<char>>& matrix){
vector<vector<int>>total(matrix.size());
for (int i = 0; i <= total.size() - 1; i++) total[i].resize(matrix.size());
for (int i = 0; i <= matrix.size() - 1; i++){
int max_area = 0;
int tmp_area = 0;
for (int j = 0; j <= matrix[0].size() - 1; j++){
if (matrix[i][j] == '1'){
tmp_area++;
if (tmp_area >= max_area) max_area = tmp_area;
}
else tmp_area = 0;
}
total[i][i] = max_area;
}
return total;
}
vector<node> chushihua_Nodes(vector<vector<char>>& matrix){
vector<node>Nodes(matrix[0].size());
for (int i = 0; i <= Nodes.size() - 1; i++){
Nodes[i].m.resize(matrix.size());
for (int j = 0; j <= matrix.size() - 1; j++)
Nodes[i].m[j].resize(matrix.size());
}
for (int i = 0; i <= Nodes.size() - 1; i++){
for (int j = 0; j <= matrix.size() - 1; j++){
if (matrix[j][i] == '1')Nodes[i].m[j][j] = 1;
else Nodes[i].m[j][j] = 0;
}
}
return Nodes;
}
int maximalRectangle(vector<vector<char>>& matrix) {
if (matrix.size() == 0)return 0;
int Hang = matrix.size(), Lie = matrix[0].size();
int total_max_area = 0;
vector<vector<int>>total=chushihua_total(matrix);
if (matrix.size() == 1) return total[0][0];
vector<node> Nodes = chushihua_Nodes(matrix);
for (int size = 2; size <= Hang; size++){
for (int i = 0; i <= Hang - size; i++){
int j = i + size - 1;
int max_area = 0,tmp=0;
for (int begin = 0; begin <= Lie - 1; begin++){
if (Nodes[begin].m[i][j - 1] == 0 || Nodes[begin].m[j][j] == 0){ tmp = 0; Nodes[begin].m[i][j] = 0; }
else {
int k= Nodes[begin].m[i][j - 1] + Nodes[begin].m[j][j];
Nodes[begin].m[i][j] = k;
tmp += k;
}
if (tmp >= max_area) max_area = tmp;
}
max_area = max(total[i][j - 1], max_area);
max_area = max(total[j][j],max_area);
total[i][j] = max_area;
total_max_area = max(max_area, total_max_area);
}//end for i
}//end for size
return total_max_area;
}