【力扣】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;
    }
}
相关推荐
许小燚28 分钟前
LeetCode——456. 132 模式
算法·leetcode·职场和发展
月熊35 分钟前
企业级WEB应用服务器TOMCAT
java·前端·tomcat
现在,此刻1 小时前
java面试题储备4: 谈谈对es的理解
java·开发语言·elasticsearch
骇客野人1 小时前
java实用工具类
java·开发语言·python
油丶酸萝卜别吃1 小时前
java中在多线程的情况下安全的修改list
java·安全·list
sali-tec4 小时前
C# 基于halcon的视觉工作流-章29-边缘提取-亚像素
开发语言·图像处理·算法·计算机视觉·c#
屁股割了还要学5 小时前
【数据结构入门】堆
c语言·开发语言·数据结构·c++·考研·算法·链表
HuiSoul2006 小时前
Spring MVC
java·后端·spring mvc
摇滚侠8 小时前
面试实战 问题二十四 Spring 框架中循环依赖问题的解决方法
java·后端·spring
三木水10 小时前
Spring-rabbit使用实战七
java·分布式·后端·spring·消息队列·java-rabbitmq·java-activemq