• 代码随想录算法训练营day60|84.柱状图中最大的矩形 |完结撒花~


    84.柱状图中最大的矩形

    力扣题目链接

    给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。

    求在该柱状图中,能够勾勒出来的矩形的最大面积。

    img

    img

    • 1 <= heights.length <=10^5

    • 0 <= heights[i] <= 10^4

    • 暴力解法

    class Solution {
        public int largestRectangleArea(int[] heights) {
            int res=0;
            for(int i=0;i<heights.length;i++){
                int left=i;
                int right=i;
                for(;left>=0;left--){
                    if(heights[left]<heights[i]) break;
                }
                for(;right<heights.length;right++){
                    if(heights[right]<heights[i]) break;
                }
                int w=right-left-1;
                int h=heights[i];
                res=Math.max(res,w*h);
            }
            return res;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 单调栈解法

    求左右两边小的, 用单调递减栈

    主要就是分析清楚如下三种情况:

    • 情况一:当前遍历的元素heights[i]大于栈顶元素heights[st.top()]的情况
    • 情况二:当前遍历的元素heights[i]等于栈顶元素heights[st.top()]的情况
    • 情况三:当前遍历的元素heights[i]小于栈顶元素heights[st.top()]的情况

    头尾要加0 ,如果数组本身就是升序的,例如[2,4,6,8],那么入栈之后 都是单调递减,一直都没有走 情况三 计算结果的哪一步,所以最后输出的就是0了,那么结尾加一个0,就会让栈里的所有元素,走到情况三的逻辑。如图:

    img

    那么结尾加一个0,就会让栈里的所有元素,走到情况三的逻辑。

    开头为什么要加元素0?

    如果数组本身是降序的,例如 [8,6,4,2],在 8 入栈后,6 开始与8 进行比较,此时我们得到 mid(8),rigt(6),但是得不到 left。

    (mid、left,right 都是对应版本一里的逻辑)

    因为 将 8 弹出之后,栈里没有元素了,那么为了避免空栈取值,直接跳过了计算结果的逻辑。

    之后又将6 加入栈(此时8已经弹出了),然后 就是 4 与 栈口元素 8 进行比较,周而复始,那么计算的最后结果resutl就是0。 如图所示:

    img

    所以我们需要在 height数组前后各加一个元素0。

    整体代码如下:

    class Solution {
        public int largestRectangleArea(int[] heights) {
            int res=0;
            int[] newheights=new int[heights.length+2];
            System.arraycopy(heights,0,newheights,1,heights.length);
            newheights[0]=0;
            newheights[heights.length+1]=0;
            Deque<Integer> stack=new LinkedList<>();
            stack.push(0);
            
            for(int i=1;i<newheights.length;i++){
                while(!stack.isEmpty()&&newheights[i]<newheights[stack.peek()]){
                    int mid=stack.peek();
                    stack.pop();
                    int w=i-stack.peek()-1;
                    int h=newheights[mid];
                    res=Math.max(res,w*h);
                }
                stack.push(i);
            }
            return res;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
  • 相关阅读:
    MySQL学习day01
    【技术积累】HTML+CSS+JavaScript中的基础知识【四】
    二十四节气之立秋
    HTML List label Ordered list Unodered list Definition list
    高效PPT制作与演示技巧大揭秘
    Vue一些你不知道的东西
    整合:qlib的AI导向的框架与backtrader的事件驱动与实盘
    FastJSON将对象转JSON字符串引发的血案
    java接收前端easyui datagrid传递的数组参数
    idleTASK,分析。
  • 原文地址:https://blog.csdn.net/xinrenne/article/details/133213649