August 05, 2019

84. Largest Rectangle in Histogram

84. Largest Rectangle in Histogram

Sol 1. Brute Force (Optimized) - 3ms

遍历数组,每找到一个局部峰值,然后向前遍历所有的值,算出共同的矩形面积,每次对比保留最大值。只在局部峰值处理,是因为非局部峰值处的情况,后面的局部峰值都可以包括。(参考这里

Time = O(n^2), space = O(1)

class Solution {
    public int largestRectangleArea(int[] heights) {
        if (heights == null || heights.length == 0) {
            return 0;
        }
        int largestArea = 0;
        for (int i = 0; i < heights.length; i++) {
            if (i == heights.length - 1 || heights[i] > heights[i + 1]) {
                int curHeight = heights[i];
                for (int j = i; j >= 0; j --) {
                    curHeight = Math.min(curHeight, heights[j]);
                    int curArea = curHeight * (i - j + 1);
                    largestArea = Math.max(largestArea, curArea);
                }
            }
        }
        return largestArea;
    }
}

Sol 2. 单调栈 - 9ms

Maintain a stack to make sure the columns whose indices are stored in the stack form an ascending order.
维护一个栈,用来保存递增序列,注意栈里存的是index。我们需要一个递增栈,当遇到大的数字直接进栈,而当遇到小于栈顶元素的数字时,就取出栈顶元素进行处理。(依旧参考这里

Time = O(n), Space = O(n)

class Solution {
    public int largestRectangleArea(int[] heights) {
        if (heights == null || heights.length == 0) {
            return 0;
        }
        Deque<Integer> stack = new LinkedList<>();
        int res = 0;
        for (int i = 0; i <= heights.length; i++) { // 多loop一次,i = heights.length时是最后一次循环,目的是把栈里所有元素都弹出来。
            int cur = (i == heights.length) ? -1 : heights[i]; // 最后一次循环,把cur值设为-1,为了把栈里所有元素弹出。
            while (!stack.isEmpty() && heights[stack.peekFirst()] >= cur) { // 取stack.peekFirst()为当前元素,它所对应的柱子的height比cur高。
                int height = heights[stack.pollFirst()]; // 弹出当前元素。它所对应的柱子的右边界一定是cur,左边界是stack里它前面元素对应的柱子,左右两边对应柱子高度都小于height。
                int width = stack.isEmpty() ? i : i - stack.peekFirst() - 1; // stack.isEmpty()表示当前元素是stack里唯一的元素已经被弹出,找不到左边界,取-1为左边界。
                res = Math.max(res, height * width); // 求当前元素高度(height)的长方形面积,更新res。
            }
            stack.offerFirst(i);
        }
        return res;
    }
}

Sol 0, DISCARDED. Brute Force (Two Pointers) - 276 ms

Time = O(n^2), Space = O(1)

class Solution {
    public int largestRectangleArea(int[] heights) {
        if (heights == null || heights.length == 0) {
            return 0;
        }
        int res = 0;
        for (int i = 0; i < heights.length; i++) {
            int l = i - 1;
            int r = i + 1;
            while (l >= 0 && heights[l] >= heights[i]) {
                l --;
            }
            while (r < heights.length && heights[r] >= heights[i]) {
                r ++;
            }
            int w = r - l - 1;
            int h = heights[i];
            res = Math.max(res, w * h);
        }
        return res;
    }
}
comments powered by Disqus