221. Maximal Square && 85. Maximal Rectangle && 84. Largest Rectangle in Histogram
221. Maximal Square
Given a 2D binary matrix filled with 0's and 1's, find the largest square containing only 1's and return its area.For example, given the following matrix:
1 0 1 0 0 1 0 1 1 1 1 1 1 1 1 1 0 0 1 0Return 4.
Hide Tags
public class Solution { /** * dp[i][j] denotes the maximal size of the square that can be achieved at point (i, j) * dp[0][j] = matrix[0][j] (topmost row) * dp[i][0] = matrix[i][0] (leftmost column) * For i > 0 and j > 0: * if matrix[i][j] = 0, dp[i][j] = 0 * if matrix[i][j] = 1, dp[i][j] = min(dp[i-1][j], dp[i][j-1], dp[i-1][j-1]) + 1 */ public int maximalSquare(char[][] matrix) { if (matrix.length == 0) return 0; int row = matrix.length; int col = matrix[0].length; int maxLen = 0; int[][] dp = new int[row][col]; for (int c = 0; c < col; ++c) { dp[0][c] = matrix[0][c] - '0'; maxLen = Math.max(maxLen, dp[0][c]); } for (int r = 1; r < row; ++r) { dp[r][0] = matrix[r][0] - '0'; maxLen = Math.max(maxLen, dp[r][0]); } for (int r = 1; r < row; ++r) { for (int c = 1; c < col; ++c) { if (matrix[r][c] == '1') { dp[r][c] = Math.min(Math.min(dp[r][c - 1], dp[r - 1][c - 1]), dp[r - 1][c]) + 1; maxLen = Math.max(dp[r][c], maxLen); // update maxLen } } } return maxLen * maxLen; } }
85. Maximal Rectangle
Given a 2D binary matrix filled with 0's and 1's, find the largest rectangle containing only 1's and return its area.
For example, given the following matrix:
1 0 1 0 0 1 0 1 1 1 1 1 1 1 1 1 0 0 1 0Return 6.
Hide Tags
public class Solution { public int maximalRectangle(char[][] matrix) { if (matrix == null || matrix.length == 0 || matrix[0].length == 0) return 0; int[] height = new int[matrix[0].length]; for (int c = 0; c < matrix[0].length; ++c) { if (matrix[0][c] == '1') height[c] = 1; } int maxArea = largestRectangleArea(height); for (int r = 1; r < matrix.length; ++r) { //convert the problem to 84. Largest Rectangle in Histogram //transform the range [row_0, row_r] to histograms. for (int c = 0; c < matrix[0].length; ++c) { if (matrix[r][c] == '1') height[c] += 1; else height[c] = 0; } //get the maximum area for each row of histogram. maxArea = Math.max(maxArea, largestRectangleArea(height)); } return maxArea; } private int largestRectangleArea(int[] height) { int len = height.length; Stack<Integer> s = new Stack<>(); int maxArea = 0; for (int i = 0; i <= len; ++i) { int h = (i == len ? 0 : height[i]); //height of the synthetic "termination bar" is 0. //when current bar is higher, we can continue to look to the right if (s.isEmpty() || h >= height[s.peek()]) { s.push(i); } //when current bar is lower, it is good enough to determine areas for bars, which are to the left and lower than current bar. else { int stackTopHeight = height[s.pop()]; //right index is the index of the first bar, which is less than and to the right of current bar int rightIndex = i; //left index is the index of the first bar, which is less than and to the left of current bar int leftIndex = s.isEmpty() ? -1 : s.peek(); int width = rightIndex - leftIndex - 1; maxArea = Math.max(maxArea, stackTopHeight * width); --i; //keep i the same for next loop } } return maxArea; } }
84. Largest Rectangle in Histogram
This can be treated as a special case of 85 where the last row is all ones.
Given n non-negative integers representing the histogram's bar height where the width of each bar is 1, find the area of largest rectangle in the histogram.

Above is a histogram where width of each bar is 1, given height = [2,1,5,6,2,3].

The largest rectangle is shown in the shaded area, which has area = 10 unit.
For example,
Given heights = [2,1,5,6,2,3],
return 10.
Check this for two solutions: http://www.geeksforgeeks.org/largest-rectangle-under-histogram/
1. O(nlogn) Divide and Conquer solution:
The idea is to find the minimum value in the given array.
(Use segment tree to find minimum in a range. http://www.geeksforgeeks.org/segment-tree-set-1-range-minimum-query/)
Once we have index of the minimum value, the max area is maximum of following three values.
a) Maximum area in left side of minimum value (Not including the min value)
b) Maximum area in right side of minimum value (Not including the min value)
c) Number of bars multiplied by minimum value.
a) Maximum area in left side of minimum value (Not including the min value)
b) Maximum area in right side of minimum value (Not including the min value)
c) Number of bars multiplied by minimum value.
2. Stack based.
public class Solution { //calculate the maximum area for each bar by looking at the right side. public int largestRectangleArea(int[] height) { int len = height.length; Stack<Integer> s = new Stack<>(); int maxArea = 0; for (int i = 0; i <= len; ++i) { int h = (i == len ? 0 : height[i]); //height of the synthetic "termination bar" is 0. //when current bar is higher, we can continue to look to the right if (s.isEmpty() || h >= height[s.peek()]) { s.push(i); } //when current bar is lower, it is good enough to determine areas for bars, which are to the left and lower than current bar. else { int stackTopHeight = height[s.pop()]; //right index is the index of the first bar, which is less than and to the right of current bar int rightIndex = i; //left index is the index of the first bar, which is less than and to the left of current bar int leftIndex = s.isEmpty() ? -1 : s.peek(); int width = rightIndex - leftIndex - 1; maxArea = Math.max(maxArea, stackTopHeight * width); --i; //keep i the same for next loop } } return maxArea; } }

浙公网安备 33010602011771号