zoukankan      html  css  js  c++  java
  • 【LeetCode】84.柱状图中最大的矩形

    题目链接

    84. 柱状图中最大的矩形

    题目描述

    解题思路

    暴力法

    对于每一个高度height[i],我们可以向左向右遍历,然后算出该高度往左往右最多可以延申至何处,这样就能算出该高度对应的面积,枚举所有高度然后求出最大值。

    时间复杂度:O(n)

    空间复杂度:O(1)

    超时!

    单调栈

    以上暴力写法 Java 可以通过,但我们不妨想一下这里的双重循环是否可以优化?

    我们每遍历到当前柱体 i 时:暴力解法中我们需要再嵌套一层 while 循环来向左找到第一个比柱体 i 高度小的柱体,这个过程是 O(N) 的;
    那么我们可以 O(1)的获取柱体 i 左边第一个比它小的柱体吗?答案就是单调增栈,因为对于栈中的柱体来说,栈中下一个柱体就是左边第一个高度小于自身的柱体。

    因此做法就很简单了,我们遍历每个柱体,若当前的柱体高度大于等于栈顶柱体的高度,就直接将当前柱体入栈,否则若当前的柱体高度小于栈顶柱体的高度,说明当前栈顶柱体找到了右边的第一个小于自身的柱体,那么就可以将栈顶柱体出栈来计算以其为高的矩形的面积了。

    小trick:为长度数组首位加上两个0,便于计算,同时可以解决高度递增序列现象问题。

    AC代码

    暴力法

    class Solution {
        public int largestRectangleArea(int[] heights) {
            int area = 0, n = heights.length;
            // 遍历每个柱子,以当前柱子的高度作为矩形的高 h,
            // 从当前柱子向左右遍历,找到矩形的宽度 w。
            for (int i = 0; i < n; i++) {
                int w = 1, h = heights[i], j = i;
                while (--j >= 0 && heights[j] >= h) {
                    w++;
                }
                j = i;
                while (++j < n && heights[j] >= h) {
                    w++;
                }
                area = Math.max(area, w * h);
            }
    
            return area;
        }
    }
    

    单调栈法

    class Solution {
        public int largestRectangleArea(int[] heights) {
            int ans = 0;
            int cHeights[] = new int[heights.length+2];
            cHeights[0] = 0;
            cHeights[heights.length+1] = 0;
            for(int i = 1; i < heights.length+1; i++){
                cHeights[i] = heights[i-1];
            }
            Stack<Integer> st = new Stack<>();
            for(int i = 0; i < cHeights.length; i++){
                while(!st.isEmpty() && cHeights[i] < cHeights[st.peek()]){
                    int height = cHeights[st.pop()];
                    ans = Math.max(ans,height * (i - st.peek() - 1));
                }
                st.push(i);
            }
            return ans;
        }
    }
    
  • 相关阅读:
    纷享销客公司产品能力学习笔记
    有质量的两道面试题
    java项目启动时执行指定方法
    css银行卡号样式
    swiper6使用鼠标滚轮失效退回swiper4即可
    vue-swiper Demo
    vue点击下载图片
    跨域请求发送数据在body里,java后台接收
    跨域,跨服务session获取不到,前后台不会传输Cookie,sessionId不一致
    Windows下 redis命令及配置
  • 原文地址:https://www.cnblogs.com/XDU-Lakers/p/14194048.html
Copyright © 2011-2022 走看看