A summary of the monotonous stack

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 Falseand Truefind one of the biggest rectangular, which makes the value of all Trueoutput 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;
    }
}

 

Published 562 original articles · won praise 13 · views 170 000 +

Guess you like

Origin blog.csdn.net/u013325815/article/details/103946328
Recommended