【力扣】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 <= heightsi <= 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;
    }
}
相关推荐
春弦_21 小时前
自用算法整理二
数据结构·算法·图论
缓慢更新21 小时前
审批的加签与会签:多人意见怎么合
android·java·数据库·低代码·rxjava
hetao17338371 天前
2026-10-22~23 hetao1733837 的刷题记录
c++·算法
yuniko-n1 天前
【JUC】volatile 非原子性深入解析
java
java_nnnn1 天前
LeetCode刷题滑动窗口(串联所有单词的子串+最小覆盖的子串)Java
算法·leetcode·职场和发展
sun_weitao1 天前
极简版 MCP 工具实现方案
java·linux·服务器
Navigator_Z1 天前
LeetCode //C - 1301. Number of Paths with Max Score
c语言·算法·leetcode
金銀銅鐵1 天前
[Java] 展示增删元素时 LinkedList 的内部变化
java·后端·ai编程
卡卡~~1 天前
“101计划”核心课程实践教材《数据实验结构指导-C++语言版》题目集
开发语言·c++·学习·算法
企业数字化笔记1 天前
AI视频增强后画质怎么验收?插值基线、伪细节与帧间闪烁的检查方法
人工智能·算法·音视频