每日一题——柱状图中最大的矩形

菜鸡每日一题系列打卡84

每天一道算法题目 

小伙伴们一起留言打卡

坚持就是胜利,我们一起努力!

题目描述(引自LeetCode)

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

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

以上是柱状图的示例,其中每个柱子的宽度为1,给定的高度为[2,1,5,6,2,3]。

图中阴影部分为所能勾勒出的最大矩形面积,其面积为10个单位。

示例:
输入: [2,1,5,6,2,3]
输出: 10

题目分析

这道题目最容易想到的是暴力法,通过双重for循环枚举高度(或者宽度),从而得到柱状图中最大的矩形,但基于暴力搜索的时间复杂度为O(n^2),我们需要对此进行优化。

这时候就需要用到一种经典的数据结构——单调栈,其实就是一种栈,只不过其中的元素是有序的。值得注意的是,通过单调栈维护小于柱子i的高度值,需要注意栈为空时设置哨兵。

话不多说,上代码!

代码实现

class Solution {


    public int largestRectangleArea(int[] heights) {
        if (heights == null || heights.length == 0) return 0;


        int length = heights.length;
        int[] left = new int[length];
        int[] right = new int[length];
        Arrays.fill(right, length);


        Stack<Integer> stack = new Stack<Integer>();
        for (int i = 0; i < length; i++) {
            while (!stack.isEmpty() && heights[stack.peek()] >= heights[i]) right[stack.pop()] = i;
            left[i] = stack.isEmpty() ? -1 : stack.peek();
            stack.push(i);
        }


        int result = 0;
        for (int i = 0; i < length; i++) {
            int tmp = (right[i] - left[i] - 1) * heights[i];
            if (tmp > result) result = tmp;
        }
        return result;
    }


}

代码分析

对代码进行分析,程序采用了单调栈进行实现,每一个位置只会入栈一次(在枚举到它时),并且最多出栈一次,因此单调栈的时间复杂度为O(n);而就空间而言,采用了额外的数组空间和单调栈空间,空间复杂度为O(n)。

执行结果

学习 | 工作 | 分享

????长按关注“有理想的菜鸡

只有你想不到,没有你学不到

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章