zoukankan      html  css  js  c++  java
  • 84. Largest Rectangle in Histogram

    Problem statment:

    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 heights = [2,1,5,6,2,3], return 10.

    Solutions one:

    Intuitively, brute force is the first solution of most people(includeing me), the time complexity is very high(O(n*n*n), n is the size of input). It is no doubt that OJ submission will fail. A smart move to solve this problem is stack. But, it is hard to figure it out.

    Compared with storing the value of heights, each element in stack is the index of heights. Because we need to calculate the area, index is helpful for us to calculate the length.

    The policy for push in and pop from the stack is:

    (stack is empty  || current_value  >= stack.top()) --> push in to stack

    otherwist, pop from stack and update the max area.

    There is a tricky is essential, we need add a zero to the end of heights, otherwise, we can not get the right answer. The purpose is to pop all element from stack and update the max area.

    For example, if the stack is <1, 2, 3, 0>(for illustration purpose, actually stack stores the index). When for loop gets to 0, current position is 7. The processing is as following:

    • 3(index is 6) is popped from the stack, the element in front of 3 is 2(index is 5), it means the minimum height after 2 to end is 3. The length is 7 - 5 - 1, max area is 3.
    • Then, 2 is popped from the stack, the element in front of 2 is 1(index is 1). it means the minimum height after 1, till end is 2. the length is 7 - 1 - 1. we get the maximum area is 2 * 5 = 10.
    • In the end, 1 is poped from the stack, it is the minimum height in this array and stack is empty, the total length is 7, which is the length of the array.

    class Solution {
    public:
        int largestRectangleArea(vector<int>& heights) {
            if(heights.empty()){
                return 0;
            }
            heights.push_back(0);
            stack<int> stk; // idx
            int max_area = 0;
            for(int ix = 0; ix < heights.size(); ix++){
                if(stk.empty() || heights[ix] >= heights[stk.top()]){
                    stk.push(ix);    
                } else {
                    while(!stk.empty() && heights[stk.top()] > heights[ix] ){
                        int idx = stk.top();
                        stk.pop();
                        max_area = max(max_area, heights[idx] * (stk.empty()? ix : ix - stk.top() - 1));   
                    }
                    stk.push(ix);
                } 
            }
            return max_area;
        }
    };

    Solution two:

    This solution from online articles. I like this solutions, it is simple to understand and easy to implement. loops to find a local max value, and goes back  to update the max area. No extra data structure.

    class Solution {
    public:
        int largestRectangleArea(vector<int>& heights) {
            int max_area = 0;
            for(int i = 0; i < heights.size(); i++){
                if(i + 1 < heights.size() && heights[i] <= heights[i + 1]){
                    continue;
                } else {
                    // find a local maximum value
                    // loop back to update max area
                    int min_height = INT_MAX;
                    int cur_area = 0;
                    // loop back to find the update the max area
                    for(int j = i; j >= 0; j--){
                        min_height = min(min_height, heights[j]);
                        max_area = max(max_area, min_height * (i - j + 1));
                    }
                }
                
            }
            return max_area;
        }
    };

    Time complexity comparison:

    Although like the second solution, the drawback is obvious. The time complexity is O(n*n).

    • In best case, such as ascending array, the  time complexity is O(n) since the local maxi value is the last one, and then loop back until to the start.
    • But, in worse case, such as descending array, the time complexity is O(n * n).

    For solution one, there is an extra stack data structure, but the time complexity is O(n).

    • Loop to the end of the array.
    • For each element, they will be pushed in and popped out from the stack only once, the total time complexity is O(n).
  • 相关阅读:
    转:阅读代码
    转:三个教程
    转:C/C++程序员简历模板
    转:对于一个字节(8bit)的变量,求其二进制表示中“1”的个数
    内存偏移
    转:用C++实现的一种插件体系结构-----概述
    转:用异或实现两个数的交换的问题
    转:二级指针
    转:《链接、装载与库》里的一个错误:关于调用栈
    转:你应当如何学习C++(以及编程)(rev#1)
  • 原文地址:https://www.cnblogs.com/wdw828/p/6848177.html
Copyright © 2011-2022 走看看