`

Leetcode - Largest Rectangle in Histogram

 
阅读更多

Given n non-negative integers representing the histogram's bar height where the width of each bar is 1, find the area of largest rectangle in the histogram.

Above is a histogram where width of each bar is 1, given height = [2,1,5,6,2,3].

 

The largest rectangle is shown in the shaded area, which has area = 10 unit.

 

For example,
Given height = [2,1,5,6,2,3],
return 10.

[balabala]  

方法1: O(N^2)  处理高度数组中每个元素时,左右分别找到第一个比当前高度低的位置,分别记为left, right, 则right - left - 1就是当前高度能围成的最大矩形的宽度,据此算出面积并更新全局最大面积值。

方法2:O(N) 使用stack 保存到当前位置处的高度非递减索引值,遇到一个高度比栈顶位置低的位置 i 时暂停下来,说明 i 是stack 中那些高于位置i 的bar的右边界,正是时候停下来计算那些高度对应的矩形面积。因为stack中是非递减序列,pop直到栈顶位置的高度小于某个正在计算的高度,pop结束时的位置就是正在计算的bar 的左边界。实现有两个方式,方式1 (method2)计算每个位置到右边界围成的面积,遇到等值大数组的case会超时,方式2(method3)pop直到找出左边界时才停下来计算,在遇到等值大数组时可节约可观的计算量。

重做该题时写了method4,原意是想节省method2中的copy数组开辟的额外空间,但遇到等值大数组时超时,在eclipse中调试,打印两个for循环耗时,input是长度为300000值均为1的数组,各方法耗时情况如下:

方法 耗时
method2 74ms
method3 28ms
method4 46ms(30+ 16)
method5 34ms(19 + 14)
method6 24ms

 

method5在method4基础上调整代码写法,去除一个多余的循环体,性能得到明显提升,让我大开眼界,不过仍然无法通过leetcode中的大case。另外通过比较method5和method3也可以看出构造一个for循环本身是有比较大的开销的。所以以后coding时要避免写不必要的循环体。比较method6 和method3, method6是以空间换时间,新开多一个元素的数组,最后一个元素是整个数组的最小值,以保证前面每个高度组成的矩形都得到计算,换句话说是替换外层循环体中的!stack.isEmpty()作用,节省了while循环和循环中if中的判断计算量。

[ref] http://www.cnblogs.com/lichen782/p/leetcode_Largest_Rectangle_in_Histogram.html

 

    // method 1
    public int largestRectangleArea(int[] height) {
        if (height == null)
            return 0;
        int n = height.length;
        int max = 0;
        for (int i = 0; i < n; i++) {
            int j = i - 1;
            while (j >= 0 && height[j] >= height[i]) {
                j--;
            }
            int left = i - j;
            j = i + 1;
            while (j < n && height[j] >= height[i]) {
                j++;
            }
            int right = j - i;
            max = Math.max(max, (left + right - 1) * height[i]);
        }
        return max;
    }

    // method 2
    public int largestRectangleArea(int[] height) {
        LinkedList<Integer> stack = new LinkedList<Integer>();
        int[] h = new int[height.length + 1];
        h = Arrays.copyOf(height, h.length);
        int i = 0;
        int max = 0;
        while (i < h.length) {
            if (stack.isEmpty() || h[i] >= h[stack.peek()]) {
                stack.push(i++);
            } else {
                int currH = h[stack.pop()];
                max = Math.max(max, currH * (stack.isEmpty() ? i : (i - stack.peek() - 1)));
            }
        }
        return max;
    }

    // method 3
    public int largestRectangleArea(int[] height) {
        LinkedList<Integer> stack = new LinkedList<Integer>();
        
        int max = 0;
        int i = 0;
        
        while(i < height.length || !stack.isEmpty()){
            if(stack.isEmpty() || i < height.length && height[i] >= height[stack.peek()]){
                stack.push(i++);
            }else{
                int currH = height[stack.pop()];
                while(!stack.isEmpty() && height[stack.peek()] == currH)
                    stack.pop();
                int left = stack.isEmpty() ? -1 : stack.peek();
                max = Math.max(max, currH * (i - left - 1));
            }
        }
        
        return max;
    }
    
    // method 4
    public int largestRectangleArea4(int[] height) {
        
        if (height == null || height.length == 0)
            return 0;
        int max = 0;
        LinkedList<Integer> stack = new LinkedList<Integer>();
        
        long start = System.currentTimeMillis();
        for (int i = 0; i < height.length; i++) {
            if (stack.isEmpty() || height[i] >= height[stack.peek()]) {
                stack.push(i);
            } else {
                while (!stack.isEmpty() && height[i] <height[stack.peek()]) {
                    int curr = stack.pop();
                    while (!stack.isEmpty() && height[curr] == height[stack.peek()]) {
                        stack.pop();
                    }
                    int width = stack.isEmpty() ? i : (i - stack.peek() - 1);
                    max = Math.max(max, height[curr] * width);
                }
                stack.push(i);
            }
        }
        System.out.println("part1=" + (System.currentTimeMillis() - start));
        start = System.currentTimeMillis();
        int rightBound = height.length;
        while (!stack.isEmpty()) {
            int curr = stack.pop();
            while (!stack.isEmpty() && height[curr] == height[stack.peek()]) {
                stack.pop();
            }
            int width = stack.isEmpty() ? rightBound : (rightBound - stack.peek() - 1);
            max = Math.max(max, height[curr] * width);
        }
        System.out.println("part2=" + (System.currentTimeMillis() - start));
        
        return max;
    }
    
 // method 5
    public int largestRectangleArea5(int[] height) {
        
        if (height == null || height.length == 0)
            return 0;
        int max = 0;
        LinkedList<Integer> stack = new LinkedList<Integer>();
        
        long start = System.currentTimeMillis();
        int i = 0;
        while(i < height.length) {
            if (stack.isEmpty() || height[i] >= height[stack.peek()]) {
                stack.push(i++);
            } else {
                int curr = stack.pop();
                while (!stack.isEmpty() && height[curr] == height[stack.peek()]) {
                    stack.pop();
                }
                int width = stack.isEmpty() ? i : (i - stack.peek() - 1);
                max = Math.max(max, height[curr] * width);
            }
        }
        System.out.println("part1=" + (System.currentTimeMillis() - start));
        start = System.currentTimeMillis();
        int rightBound = height.length;
        while (!stack.isEmpty()) {
            int curr = stack.pop();
            while (!stack.isEmpty() && height[curr] == height[stack.peek()]) {
                stack.pop();
            }
            int width = stack.isEmpty() ? rightBound : (rightBound - stack.peek() - 1);
            max = Math.max(max, height[curr] * width);
        }
        System.out.println("part2=" + (System.currentTimeMillis() - start));
        
        return max;
    }

    // method 6
    public int largestRectangleArea6(int[] h) {
        if (h == null || h.length == 0)
            return 0;
        int max = 0;
        int[] height = new int[h.length + 1];
        for (int i = 0; i < h.length; i++) {
            height[i] = h[i];
        }
        LinkedList<Integer> stack = new LinkedList<Integer>();
        
        for (int i = 0; i < height.length; i++) {
            if (stack.isEmpty() || height[i] >= height[stack.peek()]) {
                stack.push(i);
            } else {
                while (!stack.isEmpty() && height[i] <height[stack.peek()]) {
                    int curr = stack.pop();
                    while (!stack.isEmpty() && height[curr] == height[stack.peek()]) {
                        stack.pop();
                    }
                    int width = stack.isEmpty() ? i : (i - stack.peek() - 1);
                    max = Math.max(max, height[curr] * width);
                }
                stack.push(i);
            }
        }
        return max;
    }

 

 

 

分享到:
评论

相关推荐

    LeetCode Largest Rectangle in Histogram

    在LeetCode这个著名的在线编程挑战平台上,有一道题目名为“Largest Rectangle in Histogram”(直译为“柱状图中的最大矩形”),这是一道与数据结构和算法密切相关的题目,旨在考察程序员对栈、动态规划以及几何...

    js-leetcode题解之84-largest-rectangle-in-histogram.js

    javascript js_leetcode题解之84-largest-rectangle-in-histogram.js

    python-leetcode题解之084-Largest-Rectangle-in-Histogram

    python python_leetcode题解之084_Largest_Rectangle_in_Histogram

    c语言-leetcode题解之0084-largest-rectangle-in-histogram.zip

    c c语言_leetcode题解之0084_largest_rectangle_in_histogram.zip

    leetcode1-240题中文题解,md格式,java

    6. leetCode-84-Largest-Rectangle-in-Histogram.md:第84题,柱状图中最大的矩形,涉及到数组处理和栈的数据结构。 7. leetcode-130-Surrounded-Regions.md:第130题,包围的区域,可能涉及二维数组处理和深度优先...

    LargestRectangleInHistogram

    http://blog.csdn.net/two_water/article/details/53004027 LeetCode_直方图最大面积(Largest Rectangle in Histogram)

    leetcode卡-Array-LeetCode-Solution:数组-LeetCode-解决方案

    如"最宽的水平条"(Largest Rectangle in Histogram)。 5. **前缀和与后缀和**:通过计算数组的累积和,可以快速求解区间和问题。例如"连续子数组的最大和"(Maximum Subarray)。 6. **动态规划**:数组问题常与...

    LeetCodemaxarea-largest-rectangle-in-a-histogram:直方图中最大的矩形

    力扣最大面积直方图中最大的矩形 给定 n 个非负整数表示直方图的条形高度,其中每个条形的宽度为 1,求直方图中最大矩形的面积。 上面是一个直方图,其中每个条的宽度为 1,给定高度 = [2,1,5,6,2,3]。...

    蓄水池算法leetcode-leetcode:leetcode

    largest-rectangle-in-histogram: 最长递增子序列: 最长公共自序列: Something about: best time to buy and sell stack: 单链表中的环,两个单链表的公共点。 populating-next-right-pointers-in-each-node-ii: ...

    股票买卖最佳时机leetcode-Java-Projects:Java项目和面试问题的存储库,用于编码面试的练习

    股票买卖最佳时机leetcode Java项目 这是 Java 项目的存储库。 它包含: 基于回溯的数独求解器。 许多编码面试问题的解决方案作为从InterviewBit 和Leetcode ...Largest_Rectangle_In_Histogram Least_C

    leetcode316-LeetCode:leetcode的解决方案

    Rectangle:单调栈(Histogram变形) Largest Rectangle in Histogram:单调栈 Island Perimeter:简单对比(map+zip的使用) or 遍历查找 Max Area of Island:DFS(本来想用DP,发现出不来) Number of Islands:DFS My ...

    LeetCode最全代码

    421 | [Maximum XOR of Two Numbers in an Array](https://leetcode.com/problems/maximum-xor-of-two-numbers-in-an-array/) | [C++](./C++/maximum-xor-of-two-numbers-in-an-array.cpp) [Python](./Python/...

    LeetCode C++全解

    1. Introduction ... Largest Rectangle in Histogram ix. Maximal Rectangle x. Palindrome Number xi. Search a 2D Matrix xii. Search for a Range xiii. Search Insert Position xiv. Find Peak Element

    Leetcode题目+解析+思路+答案.pdf

    - **Largest Rectangle in Histogram**:在直方图中找到最大的矩形面积。 - **Maximal Rectangle**:在二维矩阵中找到最大的矩形。 - **Palindrome Number**:判断一个数字是否是回文数。 - **Search a 2D ...

    leetcode2-Misc-4:杂项4

    问题二:直方图中最大的矩形(Largest Rectangle in Histogram) 这是一个经典的几何问题,需要找到直方图(一种特殊形式的柱状图)中可以构成的最大矩形面积。解决这个问题通常采用栈作为辅助数据结构。遍历每个...

    LeetCode leetcode部分题解答代码实现

    * Largest Rectangle in Histogram:给定一个直方图,返回直方图中的最大矩形面积。这个题目需要使用栈的思想,将直方图中的每个矩形分解成更小的矩形,并找到最大矩形。 * Maximal Rectangle:给定一个矩形,返回...

    LeetCode练习答案

    - **直方图中的最大矩形(Largest Rectangle in Histogram)**: 给定直方图的高度,计算能够组成的矩形的最大面积。 - **最大矩形(Maximal Rectangle)**: 在由'0'和'1'组成的二维矩阵中,找到只包含'1'的最大矩形,并...

    3、动态规划必练题(含解法).pdf

    11. **Largest Rectangle in Histogram** (柱状图中最大的矩形) 求柱状图中能构成的最大矩形面积。可以使用栈来辅助实现,维护当前高度和最大高度。 12. **Maximal Rectangle** (最大的矩形) 在一个01矩阵中找到...

Global site tag (gtag.js) - Google Analytics