0
点赞
收藏
分享

微信扫一扫

力扣算法学习day41-3

闲嫌咸贤 2022-03-11 阅读 68

文章目录

力扣算法学习day41-3

84-柱状图中最大的矩形

题目

image-20220303234748355

image-20220303234812579

代码实现

class Solution {
    public int largestRectangleArea(int[] heights) {
        // 代码随想录刷题收官之战!速度:21ms
        // 首先,比较容易想到双指针思路,就是求每个柱子为中心凹点的最大矩形面积。那么需要从左到右
        // 遍历柱子,然后每个柱子还需要遍历找它左边第一个小于它的位置,和右边第一个小于它的位置。
        // 双指针很明显时间复杂度是O(n^2),然后感觉用dp优化,很容易想到的就是dp优化双指针需要遍历
        // 的时候去找左右第一个小于的值,而这个值可以由dp数组先求得,但是实际操作我发现这个dp数组
        // 两个也是需要双重循环的估计速度差不多,就算了。
        // 然后速度优化 考虑使用单调栈(单调减,从栈顶到栈底 一次降低)(注:这里栈用于存储坐标)
        // 规则:
        // 1.如果当前栈顶元素小于或等于当前比较元素,直接压入栈.
        // 2.如果当前栈顶元素大于比较元素,弹出栈顶元素,并计算栈顶元素的面积。
        // 这里的原理是遇到小于栈顶的元素,那么一定可以确定当前栈顶的左边最小和右边最小的坐标,即
        // 这里和双指针计算的原理是一样的,只是因为单调栈的性质确定了左边保存的是比它小的第一个数,
        // 而如果遇到的比较的这个数如果比栈顶小,那又确定了它的右边遇到的第一个比它小的元素。
        // 这里计算公式是:
        // 1.宽为遇到的小于栈顶元素的坐标 - 弹出后存储为mid,栈顶元素的值 - 1; 注:如果弹出后栈为空了,那
        // 直接宽 = 1。 然后面积 = 宽 * heights[mid]
        // 这里最后还需要处理留在栈中的元素。计算原理同理。
        // 这里为了方便计算需要在头尾加上0
        int[] height = new int[heights.length+2];
        for(int i = 1;i < height.length - 1;i++){
            height[i] = heights[i-1];
        }
        LinkedList<Integer> stack = new LinkedList<>();
        int result = 0;
        
        for(int i = 0;i < height.length;i++){
            while(!stack.isEmpty() && height[i] < height[stack.peek()]){
                int mid = stack.pop();

                int x = 0;// 先设置变量x为宽,下面分两种情况赋值
                if(stack.isEmpty()){
                    x = i - mid;
                } else{
                    x = i - stack.peek() - 1;
                }

                int area = x * height[mid];
                
                if(area > result){
                    result = area;
                }
            }

            stack.push(i);
        }   

        return result;

        // 额,做完了,感觉可能动态规划会更快,明天开始复习,顺便补上dp解法。
    }
}
举报

相关推荐

力扣算法学习day20-3

力扣算法学习day27-3

力扣算法学习day13-1

力扣算法学习day12-2

0 条评论