• 算法——柱状图中最大的矩形


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

    解题思路:

    1. 首先想暴力该怎么做?
      就是依次遍历数组,求以每一个柱子为高度的最大面积,当遍历到一个元素的时候,在去找到它的左右两边第一个比它小的柱子的位置,这样就能取最大值。暴力的方法是N方的。
    2. 降低时间复杂度的方法。因为每次需要去遍历每个元素左右两边第一个比它小的位置,就很费时间。所以,可以先通过两次遍历,分别求每个元素在左右两个方向上,第一个比他小的元素的索引值,这样,就不需要每次都去重新找了。如果这个数组在一个方向上就是最小值,那么下标值就用-1或者数组的长度来代替计算。
    3. 通过单调栈的方法,就能通过一次遍历,寻找一个队列中,每个元素,在一个方向上的第一个比其小或者大的元素了。
    4. 最后,一次遍历数组,每次用之前存下来的左右两边第一个比它小的元素的下标之差,然后乘以其高度,就是以当前元素为高度的最大值,然后依次比较就是答案。
    class Solution {
        public int largestRectangleArea(int[] heights) {
            int n = heights.length;
            // 利用两个数组,存储每个元素左右两边第一个比它小的元素的下标
            int[] l = new int[n], r = new int[n];
            Deque<Integer> stack = new LinkedList<>();
            int res = 0;
    
            for(int i = 0; i < n; i++) {
            	// 如果栈顶元素比它大,就不断弹出,因为在之前的比它大的元素已经不会被用到了
                while(!stack.isEmpty() && heights[stack.peek()] >= heights[i]) {
                    stack.pop();
                }
    			// 弹到最后剩下的,就是第一个比它小的元素了
                l[i] = stack.isEmpty() ? -1 : stack.peek();
    
                stack.push(i);
            }
    
            stack = new LinkedList<>();
            for(int i = n - 1; i >= 0; i--) {
                while(!stack.isEmpty() && heights[stack.peek()] >= heights[i]) {
                    stack.pop();
                }
    
                r[i] = stack.isEmpty() ? n : stack.peek();
    
                stack.push(i);
            }
    
            for(int i = 0; i < n; i++) {
                res = Math.max(res, heights[i] * (r[i] - l[i] - 1));
            }
    
            return res;
        }
    }
    
  • 相关阅读:
    网络与系统安全第四次作业
    2018-2019-1 20189203《linux内核原理与分析》第六周作业
    《网络攻防实践》第五周作业
    《网络攻防实践》第四周作业
    《网络攻防实践》第三周作业
    《网络攻防实践》第二周作业
    《网络攻防实践》第一周作业
    《Linux内核原理与分析》第九周作业
    《Linux内核原理与分析》第八周作业
    《Linux内核原理与分析》第七周作业
  • 原文地址:https://www.cnblogs.com/lippon/p/14117630.html
Copyright © 2020-2023  润新知