84. The largest rectangle in the histogram (java implementation) --LeetCode

topic:

Given n non-negative integers, they are used to represent the height of each column in the histogram. Each pillar is adjacent to each other and has a width of 1.

Find the maximum area of ​​the rectangle that can be outlined in the histogram.
Insert picture description here
The above is an example of a histogram, where the width of each column is 1, and the given height is [2,1,5,6,2,3].
Insert picture description here

The shaded part in the figure is the largest rectangular area that can be outlined, and its area is 10 units.

Example:

输入: [2,1,5,6,2,3]
输出: 10

Solution 1: Violence

/**
 * 思路:
 * 暴力,双层for
 * 记录最大面积max,和最小柱子的高度
 * 不断向前遍历,找到每个棒子所在范围内的最小值,更新min和area
 *
 * 注意:1根柱子也可以计算面积
 */
    public int largestRectangleArea(int[] heights) {
    
    
        int max=0,minHeight;
        for (int i=0;i<heights.length;i++){
    
    
            minHeight=heights[i];
            for (int j=i;j<heights.length;j++){
    
    
                minHeight=minHeight>heights[j]?heights[j]:minHeight;
                int area = minHeight * (j - i + 1);
                max=max>area?max:area;
            }
        }
        return max;
    }

Time complexity: On^2

Space complexity: O1
Insert picture description here

Solution 2: Stack implementation

/**
 * 思路:
 * 核心思路:
 * 确定每个柱子的左右边界,一旦确定就进行area计算(确定每个棒子最大可能的面积,知道了所有的柱子最大可能面积就能找到柱状图最大面积)
 * 不断的向前遍历数组,我们是一定可以知道的是每个棒子的左边界(左边的棒子已经遍历到),但是棒子的右边界无法确定(右边的棒子还未遍历到)。
 *
 * 栈能很好能实现这个思路
 * 栈中存放初始值-1(方便第一个棒子计算面积),栈中存放的是数组的下标
 * 遍历数组
 * 如果当前值比栈中元素大就入栈(这样当前柱子的左边界就是他们在栈中的下一个元素)
 * 如果当前值比栈中元素小就把栈中元素都出栈!!出栈元素的左右边界相当于确定了(左边界是栈中的下一个元素,右边界就是这个比他小的元素),计算area和max进行比较。之后入栈当前值
 * 遍历完后,清空栈,计算面积:这个时候剩余元素的右边界都是heights.length,左边界依旧是栈中下一个元素
 */
     public int largestRectangleArea(int[] heights) {
    
    
        ArrayDeque<Integer> stack = new ArrayDeque<>();
        stack.push(-1);
        int max=0;
        for (int i=0;i<heights.length;i++){
    
    
            while (stack.peek()!=-1&&heights[i]<heights[stack.peek()]){
    
    
                int bar_heigh=heights[stack.pop()];
                int area=bar_heigh*(i-stack.peek()-1);
                max=area>max?area:max;
            }
            stack.push(i);
        }
        while (stack.peek()!=-1){
    
    
            int bar_heigh = heights[stack.pop()];
            int area=bar_heigh*(heights.length-stack.peek()-1);
            max=area>max?area:max;
        }
        return max;
    }

Time complexity: On

Space complexity: OnInsert picture description here

Solution 3: Divide and conquer

/**
 * 思路:
 * 核心思路:在最小值的左侧,和右侧才可能出现更大的面积
 * 
 * 分治
 * 终止条件,start>end
 * 找到数组的最小值,求面积
 * 子问题:在左右侧在找最大面积
 */
     public int largestRectangleArea(int[] heights) {
    
    
        return divideConquer(0,heights.length-1,heights);
    }

    private int divideConquer(int start, int end, int[] heights) {
    
    
        //Terminator
        if (start>end){
    
    
            return 0;
        }
        //process current logic
        int min=start;
        for (int i=start;i<=end;i++){
    
    
            if (heights[i]<heights[min]){
    
    
                min=i;
            }
        }
        int area=heights[min]*(end-start+1);
        //drill down
        return Math.max(area,Math.max(divideConquer(start,min-1,heights),divideConquer(min+1,end,heights)));
        //restore store
    }

Time complexity: On^2

Space complexity: O1
Insert picture description here

Guess you like

Origin blog.csdn.net/qq_38783664/article/details/110592231