Largest Rectangle in Histogram
Given non-negative integer n represents the height of each histogram, each histogram are a wide, rectangular area to find the maximum in the histogram.
Example
Example 1:
输入:[2,1,5,6,2,3]
输出:10
解释:
第三个和第四个直方图截取矩形面积为2*5=10。
Ideas: seeking maximum matrix, each element is seeking height * leftmost less than his first one element to the right of the first is less than the distance between his element;
The first such demand around the minimum, we use a monotonically increasing stack can be completed. Note that stack is kept inside index; need to be calculated because the width, the height can be known by index; but not with the calculated height width; Trapping Rain Water descending stack is used; this minimum request by incrementing the stack;
public class Solution {
/**
* @param height: A list of integer
* @return: The area of largest rectangle in the histogram
*/
public int largestRectangleArea(int[] height) {
// 需要找到每个元素对应两边第一个最小的元素;
// 这题跟Trapping Rain Water 是反着的,这里需要用单调递增栈;
if(height == null || height.length == 0) return 0;
Stack<Integer> stack = new Stack<Integer>();
int max = 0;
for(int i = 0; i <= height.length; i++){
// -1是为了把栈里面所有的元素都弹出来计算的;1,2,3,4,5,-1
int item = (i == height.length) ? -1 : height[i];
while(!stack.isEmpty() && item <= height[stack.peek()]){
int h = height[stack.pop()]; // 踢出来元素的高度;
int left = stack.isEmpty() ? 0 : stack.peek() + 1; // 左边第一个小于他的下一个
int right = i-1; // 右边第一个小于他的前一个;
int area = h * (right - left + 1); //计算可能的矩阵;
max = Math.max(max, area);
}
stack.push(i);
}
return max;
}
}
Maximal Rectangle
Give you a two-dimensional matrix, with a weight False
and True
find one of the biggest rectangular, which makes the value of all True
output its area
Example
Sample 1
输入:
[
[1, 1, 0, 0, 1],
[0, 1, 0, 0, 1],
[0, 0, 1, 1, 1],
[0, 0, 1, 1, 1],
[0, 0, 0, 0, 1]
]
输出: 6
Ideas: The above problem a little bit changes, each row of seeking Histogram, can be O (n ^ 2) to do this problem;
public class Solution {
/**
* @param matrix: a boolean 2D matrix
* @return: an integer
*/
public int maximalRectangle(boolean[][] matrix) {
if(matrix == null || matrix.length == 0 || matrix[0].length == 0) {
return 0;
}
int m = matrix[0].length;
int[] height = new int[m];
int maxarea = 0;
for(int i = 0; i < matrix.length; i++) {
for(int j = 0; j < matrix[0].length; j++) {
if(i == 0) {
height[j] = matrix[0][j] == false ? 0 : 1;
} else {
height[j] = matrix[i][j] == false ? 0 : height[j] + 1;
}
}
maxarea = Math.max(maxarea, largestRectangleArea(height));
}
return maxarea;
}
private int largestRectangleArea(int[] height) {
if(height == null || height.length == 0) {
return 0;
}
Stack<Integer> stack = new Stack<Integer>();
int maxarea = 0;
for(int i = 0; i <= height.length; i++) {
int curt = (i == height.length) ? -1 : height[i];
while(!stack.isEmpty() && curt <= height[stack.peek()]){
int h = height[stack.pop()];
int left = stack.isEmpty() ? 0 : stack.peek() + 1;
int right = i - 1;
int area = h * (right - left + 1);
maxarea = Math.max(maxarea, area);
}
stack.push(i);
}
return maxarea;
}
}
Trapping Rain Water
Gives the n non-negative integer that represents a width of each region of the X-axis 1
of FIG altitude, the altitude is calculated how much catch up to FIG. (Area) of the rain.
Ideas: the need to find every element from both sides of view, the first one of the biggest elements of both sides, water is about the biggest sides minimum - current height;
Such a monotone decreasing stack, note stack stored inside is index, to find a width;
public class Solution {
/**
* @param heights: a list of integers
* @return: a integer
*/
public int trapRainWater(int[] heights) {
if(heights == null || heights.length == 0) {
return 0;
}
Stack<Integer> stack = new Stack<Integer>();
int water = 0;
for(int i = 0; i < heights.length; i++) {
while(!stack.isEmpty() && heights[stack.peek()] <= heights[i]){
int j = stack.pop();
if(!stack.isEmpty()){
int h = Math.min(heights[stack.peek()], heights[i]) - heights[j];
int right = i - 1;
int left = stack.peek() + 1;
int w = right - left + 1;
water += w * h;
}
}
stack.push(i);
}
return water;
}
}
Max Tree
Did not repeat a given array of integers, the maximum tree established on this array is defined as follows:
- The root is the maximum number of array
- Left subtree and right subtree is the maximum of the subarray elements are separated by cutting the parent element
With a given array constructor's largest tree.
Example
Example 1:
输入:[2, 5, 6, 0, 3, 1]
输出:{6,5,3,2,#,0,1}
解释:
此数组构造的最大树是:
6
/ \
5 3
/ / \
2 0 1
Thinking: stack with monotonically decreasing as L, <x, <x .... X, <x, <x, R, (L> X, R> X) X can give his father, only L, a R is therefore, it becomes a problem to find the left and right sides of the first point is larger than X, the minimum value, then to the left and right respectively (see X is connected to the L, R of the left or right);
/**
* Definition of TreeNode:
* public class TreeNode {
* public int val;
* public TreeNode left, right;
* public TreeNode(int val) {
* this.val = val;
* this.left = this.right = null;
* }
* }
*/
public class Solution {
/**
* @param A: Given an integer array with no duplicates.
* @return: The root of max tree.
*/
public TreeNode maxTree(int[] A) {
if(A == null || A.length == 0) {
return null;
}
Stack<TreeNode> stack = new Stack<TreeNode>();
for(int i = 0; i <= A.length; i++) {
TreeNode node = (i == A.length) ? new TreeNode(Integer.MAX_VALUE)
: new TreeNode(A[i]);
while(!stack.isEmpty() && stack.peek().val <= node.val){
TreeNode curnode = stack.pop();
//核心就是安排pop出来的点,是去L,还是R的左边还是右边;
// 注意因为上面pop了,这里一定要判断一下stack是否为空;
if(!stack.isEmpty() && node.val > stack.peek().val) {
stack.peek().right = curnode;
} else {
// node.val <= stack.peek().val;
node.left = curnode;
}
}
stack.push(node);
}
return stack.pop().left;
}
}