【力扣】84. 柱状图中最大的矩形 <模拟、双指针、单调栈>

目录

【力扣】84. 柱状图中最大的矩形

给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。求在该柱状图中,能够勾勒出来的矩形的最大面积。

示例 1:

输入:heights = [2,1,5,6,2,3]

输出:10

解释:最大的矩形为图中红色区域,面积为 10

示例 2:

输入: heights = [2,4]

输出: 4

提示:

1 <= heights.length <= 1 0 5 10^5 105

0 <= heights[i] <= 1 0 4 10^4 104

题解

暴力求解

java 复制代码
public static int largestRectangleArea(int[] heights) {
    int sum = 0;
    for (int i = 0; i < heights.length; i++) {
        int left = i;
        int right = i;

        //找当前遍历元素之前第一个比它小的元素
        while (left >= 0) {
            if (heights[left] < heights[i]) {
                break;
            }
            left--;
        }

        //找当前遍历元素之后第一个比它小的元素
        while (right < heights.length) {
            if (heights[right] < heights[i]) {
                break;
            }
            right++;
        }

        int w = right - left - 1;
        int h = heights[i];
        sum = Math.max(sum, w * h);
    }
    return sum;
}

双指针

java 复制代码
public class Solution {
    public static int largestRectangleArea(int[] heights) {
        int[] minLeftIndex = new int[heights.length];
        int[] minRightIndex = new int[heights.length];


        // 记录左边第一个小于该柱子的下标
        minLeftIndex[0] = -1;
        for (int i = 1; i < heights.length; i++) {
            int t = i - 1;
            // 这里不是用if,而是不断向右寻找的过程
            while (t >= 0 && heights[t] >= heights[i]) {
                t = minLeftIndex[t];
            }
            minLeftIndex[i] = t;
        }


        // 记录每个柱子右边第一个小于该柱子的下标
        minRightIndex[heights.length - 1] = heights.length;
        for (int i = heights.length - 2; i >= 0; i--) {
            int t = i + 1;
            while (t < heights.length && heights[t] >= heights[i]) {
                t = minRightIndex[t];
            }
            minRightIndex[i] = t;
        }

        /*for (int a : minLeftIndex) {
            System.out.println(a);
        }
        System.out.println("______________________________");

        for (int a : minRightIndex) {
            System.out.println(a);
        }*/

        // 求和
        int result = 0;
        for (int i = 0; i < heights.length; i++) {
            int sum = heights[i] * (minRightIndex[i] - minLeftIndex[i] - 1);
            result = Math.max(sum, result);
        }
        return result;
    }

    public static void main(String[] args) {
        int[] heights = {2, 4, 2};
        System.out.println(largestRectangleArea(heights));
    }
}

单调栈

注意:单调栈是递减的

java 复制代码
class Solution {
    int largestRectangleArea(int[] heights) {
        Stack<Integer> st = new Stack<Integer>();
        
        // 数组扩容,在头和尾各加入一个元素,防止只递增或者只递减的数组
        int [] newHeights = new int[heights.length + 2];
        newHeights[0] = 0;
        newHeights[newHeights.length - 1] = 0;
        for (int index = 0; index < heights.length; index++){
            newHeights[index + 1] = heights[index];
        }

        heights = newHeights;
        
        st.push(0);
        int result = 0;
        // 第一个元素已经入栈,从下标1开始
        for (int i = 1; i < heights.length; i++) {
            // 注意heights[i] 是和heights[st.top()] 比较 ,st.top()是下标
            if (heights[i] > heights[st.peek()]) {
                st.push(i);
            } else if (heights[i] == heights[st.peek()]) {
                st.pop(); // 这个可以加,可以不加,效果一样,思路不同
                st.push(i);
            } else {
                while (heights[i] < heights[st.peek()]) { // 注意是while
                    int mid = st.peek();
                    st.pop();
                    int left = st.peek();
                    int right = i;
                    int w = right - left - 1;
                    int h = heights[mid];
                    result = Math.max(result, w * h);
                }
                st.push(i);
            }
        }
        return result;
    }
}
相关推荐
梦梦代码精8 小时前
BuildingAI 上部署自定义工作流智能体:5 个实用技巧
大数据·人工智能·算法·开源软件
Mr_pyx8 小时前
Spring AI 入门教程:Java开发者的AI应用捷径
java·人工智能·spring
Zephyr_08 小时前
Leedcode算法题
java·算法
流年如夢9 小时前
栈和列队(LeetCode)
数据结构·算法·leetcode·链表·职场和发展
苍煜9 小时前
Java开发IO零基础吃透:BIO、NIO、同步异步、阻塞非阻塞
java·python·nio
折哥的程序人生 · 物流技术专研9 小时前
Java面试85题图解版(一):基础核心篇
java·开发语言·后端·面试
AllData公司负责人10 小时前
通过Postgresql同步到Doris,全视角演示AllData数据中台核心功能效果,涵盖:数据入湖仓,数据同步,数据处理,数据服务,BI可视化驾驶舱
java·大数据·数据库·数据仓库·人工智能·python·postgresql
Hello.Reader10 小时前
算法基础(十)——分治思想把大问题拆成小问题
java·开发语言·算法
一只大袋鼠10 小时前
JavaWeb四种文件上传方式(下篇)
java·开发语言·springmvc·javaweb