[LeetCode] Maximal Rectangle
Maximal Rectangle
Given a 2D binary matrix filled with 0's and 1's, find the largest rectangle containing all ones and return its area. the question indicates finding the largest rectangle block formed by right all 1. Solution 1: Use Dynamic Planning. If d [I] [j] represents the largest rectangle that meets the conditions in the rectangle area in the lower right corner of matrix [I] [j. If matrix [I] [j] = '0', d [I] [j] = max (d [I-1] [j], d [I] [J-1]), if matrix [I] [j] = '1 ', then d [I] [j] = max (d [I-1] [j], d [I] [J-1], contains the maximum rectangle in the bottom right corner of matrix [I] [j ). But how can we find "contains the maximum rectangle in the bottom right corner of matrix [I] [j? I first thought of the brute force method. The Code is as follows:
Class Solution {public: int maximalRectangle (vector
> & Matrix) {int m = matrix. size (); if (m = 0) {return 0;} int n = matrix [0]. size (); if (n = 0) {return 0;} int ** d = new int * [m + 1]; for (int I = 0; I <= m; I ++) {d [I] = new int [n + 1] ;}for (int I = 0; I <= m; I ++) {d [I] [0] = 0 ;}for (int I = 0; I <= n; I ++) {d [0] [I] = 0 ;} for (int I = 1; I <= m; I ++) {for (int j = 1; j <= n; j ++) {d [I] [j] = max (d [I-1] [j], d [I] [J-1]); if (matrix [I-1] [J-1] = '1') {// calculate the area of the matrix 1 in the bottom right corner of the I-1, J-1 Element The smallest I int minI = I-1 in the I direction; while (minI> = 0 & matrix [minI] [J-1] = '1') minI --; minI = max (minI, 0); // find the smallest j int minJ = J-1 in the j direction; while (minJ> = 0 & matrix [I-1] [minJ] = '1') minJ --; minJ = max (minJ, 0); if (I-minI) * (j-minJ)> d [I] [j]) {int maxArea = 0; for (int tempI = minI; tempI <I; tempI ++) {for (int tempJ = minJ; tempJ <j; tempJ ++) {int area = getArea (matrix, tempI, I-1, tempJ, J-1); if (area! = 0) {maxArea = max (area, maxArea); break ;}} d [I] [j] = max (d [I] [j], maxArea) ;}}} int result = d [m] [n]; for (int I = 0; I <= m; I ++) {delete [] d [I];} delete [] d; return result;} private: int max (int a, int B) {return a> B? A: B;} int getArea (vector
> & Matrix, int startI, int endI, int startJ, int endJ) {bool allOne = true; for (int I = startI; I <= endI; I ++) {for (int j = startJ; j <= endJ; j ++) {if (matrix [I] [j] = '0') {allOne = false; break;} if (! AllOne) {break ;}}if (allOne) {return (endI-startI + 1) * (endJ-startJ + 1);} else {return 0 ;}}};
But the running time is 874 ms, which is obviously incorrect, because the worst-case running time complexity is O (m2 * n2) solution 2 in order to calculate the "maximum rectangle block containing matrix [I] [j] in the lower right corner" as soon as possible, the height of 1 in each row can be recorded. The Code is as follows:
Class Solution {public: int maximalRectangle (vector
> & Matrix) {int m = matrix. size (); if (m = 0) {return 0;} int n = matrix [0]. size (); if (n = 0) {return 0;} // The Dynamic Programming array int ** d = new int * [m + 1]; for (int I = 0; I <= m; I ++) {d [I] = new int [n + 1] ;}for (int I = 0; I <= m; I ++) {d [I] [0] = 0 ;}for (int I = 0; I <= n; I ++) {d [0] [I] = 0 ;}// the int * h = new int [n + 1] of the full 1 record; for (int I = 0; I <= n; I ++) {h [I] = 0 ;}for (int I = 1; I <= m; I ++) {for (int j = 1; j <= n; j ++) {d [I] [j] = max (d [I-1] [j], d [I] [J-1]); if (matrix [I-1] [J-1] = '1') {h [j] ++; int maxArea = h [j]; int minH = h [j]; for (int k = J-1; k> 0; k --) {if (h [k] = 0) {break;} minH = minH> h [k]? H [k]: minH; maxArea = max (maxArea, minH * (j-k + 1 ));} d [I] [j] = max (d [I] [j], maxArea) ;}else {h [j] = 0 ;}}} int result = d [m] [n]; for (int I = 0; I <= m; I ++) {delete [] d [I];} delete [] d; delete [] h; return result;} private: int max (int a, int B) {return a> B? A: B ;}};
In this way, the time complexity of the algorithm is reduced to O (m * n), which is a bad situation. The running time in LeetCode is reduced to 28 ms. Solution 3: Later, I thought that I didn't need to record the maximum value at a certain position. I only needed to record the global maximum value, that is, I don't need the idea of dynamic planning. below is the improved code of solution 2:
Class Solution {public: int maximalRectangle (vector
> & Matrix) {int m = matrix. size (); if (m = 0) {return 0;} int n = matrix [0]. size (); if (n = 0) {return 0;} // int * h = new int [n]; for (int I = 0; I
= 0; k --) {if (h [k] = 0) {break;} minH = minH> h [k]? H [k]: minH; maxArea = max (maxArea, minH * (j-k + 1);} result = max (result, maxArea );} else {h [j] = 0 ;}} return result;} private: int max (int a, int B) {return a> B? A: B ;}};
In this way, although the time complexity has not changed, it saves a lot of space and time. LeetCode run time is 19 ms solution 4: After checking it online, this question can still be completed in the time complexity of O (m * n), and the stack concept is used, for details, see region. The following code is used:
Class Solution {public: int maximalRectangle (vector
> & Matrix) {int m = matrix. size (); if (m = 0) {return 0;} int n = matrix [0]. size (); if (n = 0) {return 0;} int result = 0; // The int * h = new int [n + 1] of all 1 records; // apply for one more space. I will know its benefits later. for (int I = 0; I <= n; I ++) {h [I] = 0 ;} for (int I = 0; I
S; int tempMax = 0; // areabool hCounted = false; for (int j = 0; j <= n; j ++) {if (! HCounted & j! = N) {if (matrix [I] [j] = '1') {h [j] ++;} else {h [j] = 0 ;} hCounted = true;} if (s. empty () | h [s. top ()]
B? A: B ;}};