来源,leetcode 每日一题 85. 最大矩形
例如:
输入: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"]]输出:0
解题思路
- 暴力方法:最原始地,我们可以列举每个可能的矩形。这可以通过遍历所有的(x1, y1) (x2, y2) 坐标,并以它们为对角顶点来完成。该方法过慢,不足以通过所有测试用例。
动态规划 - 使用柱状图的优化暴力方法:
- 遍历得到每个点的最大宽度
- 计算以每个点为右下角的矩形的最大面积
。
class Solution {public:int maximalRectangle(vector<vector<char>>& matrix) {int rows = matrix.size();if (rows == 0) {return 0;}int columns = matrix[0].size();if (columns == 0) {return 0;}vector<vector<int>> maxWidth(rows, vector<int>(columns));for (int i = 0; i < rows; i++) {if (matrix[i][0] == '1') {maxWidth[i][0] = 1;}for (int j = 1; j < columns; j++) {if (matrix[i][j] == '1') {maxWidth[i][j] = maxWidth[i][j-1] + 1;}}}int max_area = 0;for (int j = 0; j < columns; j++) {for (int i = 0; i < rows; i++) {if (maxWidth[i][j] == 0) {continue;}int height = 1;int width = maxWidth[i][j];max_area = max(width * height, max_area);for (int h = i + 1; h < rows; h++) {if (maxWidth[h][j] != 0) {height += 1;width = min(maxWidth[h][j], width);max_area = max(height*width, max_area);} else {break;}}}}return max_area;}};
- 遍历得到每个点的最大宽度
优化
class Solution {
public int maximalRectangle(char[][] matrix) {if(matrix.length == 0) return 0;int m = matrix.length;int n = matrix[0].length;int[] left = new int[n]; // initialize left as the leftmost boundary possibleint[] right = new int[n];int[] height = new int[n];Arrays.fill(right, n); // initialize right as the rightmost boundary possibleint maxarea = 0;for(int i = 0; i < m; i++) {int cur_left = 0, cur_right = n;// update heightfor(int j = 0; j < n; j++) {if(matrix[i][j] == '1') height[j]++;else height[j] = 0;}// update leftfor(int j=0; j<n; j++) {if(matrix[i][j]=='1') left[j]=Math.max(left[j],cur_left);else {left[j]=0; cur_left=j+1;}}// update rightfor(int j = n - 1; j >= 0; j--) {if(matrix[i][j] == '1') right[j] = Math.min(right[j], cur_right);else {right[j] = n; cur_right = j;}}// update areafor(int j = 0; j < n; j++) {maxarea = Math.max(maxarea, (right[j] - left[j]) * height[j]);}return maxarea;}
} ```
