【Lintcode】122.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.

histogram

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

histogram

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

题解:

  做编程题一定要自己AC了再去看discussion,之前一直草草的刷题,感觉忘得好快,尤其是边界条件的处理上一点长进也没有,这次hard题做了半个多小时,从开始看题到提交(提交了3次,都是小错误。。。太不细心了,这更加说明了白板编程的重要性,不要用IDE),完全自己码出来,以后会坚持这样做,否则去面试什么的肯定跪,也不利于思维逻辑能力的提高。

Solution 1 ()

class Solution {
public:
    int largestRectangleArea(vector<int> height) {
        if (height.empty()) return 0;
        stack<int> high;
        int maxArea = 0;
        
        high.push(0);
        height.push_back(0);
        for (int i = 1; i < height.size(); ++i) {
            while (!high.empty() && height[i] < height[high.top()]) {
                int index = high.top();
                high.pop();
                if (high.empty()) {
                    maxArea = max((i - 0) * height[index], maxArea);
                } else {
                    maxArea = max((i - high.top() - 1) * height[index], maxArea);
                }
            }
            high.push(i);
        }

        return maxArea;
    }
};

Solution 2 ()

class Solution {
public:
    int largestRectangleArea(vector<int> &height) {   
        int ret = 0;
        height.push_back(0);
        vector<int> index;
            
        for(int i = 0; i < height.size(); i++) {
            while(index.size() > 0 && height[index.back()] >= height[i]) {
                int h = height[index.back()];
                index.pop_back();
                        
                int sidx = index.size() > 0 ? index.back() : -1;
                if(h * (i-sidx-1) > ret)
                ret = h * (i-sidx-1);
            }
            index.push_back(i);
        }
            
        return ret;
    }
};

  Diveide and Conquer 思想比较容易懂, 就是写起来的时候边界条件有点麻烦。

Solution 3 ()

class Solution {
    int maxCombineArea(const vector<int> &height, int s, int m, int e) {
        // Expand from the middle to find the max area containing height[m] and height[m+1]
        int i = m, j = m+1;
        int area = 0, h = min(height[i], height[j]);
        while(i >= s && j <= e) {
            h = min(h, min(height[i], height[j]));
            area = max(area, (j-i+1) * h);
            if (i == s) {
                ++j;
            }
            else if (j == e) {
                --i;
            }
            else {
                // if both sides have not reached the boundary,
                // compare the outer bars and expand towards the bigger side
                if (height[i-1] > height[j+1]) {
                    --i;
                }
                else {
                    ++j;
                }
            }
        }
        return area;
    }
    int maxArea(const vector<int> &height, int s, int e) {
        // if the range only contains one bar, return its height as area
        if (s == e) {
            return height[s];
        }
        // otherwise, divide & conquer, the max area must be among the following 3 values
        int m = s + (e-s)/2;
        // 1 - max area from left half
        int area = maxArea(height, s, m);
        // 2 - max area from right half
        area = max(area, maxArea(height, m+1, e));
        // 3 - max area across the middle
        area = max(area, maxCombineArea(height, s, m, e));
        return area;
    }
public:
    int largestRectangleArea(vector<int> &height) {
        if (height.empty()) {
            return 0;
        }
        return maxArea(height, 0, height.size()-1);
    }
};

为什么下面的代码过不了???

class Solution {
public:
    int largestRectangleArea(vector<int> &height) {   
        if (height.empty()) return 0;
        
        return maxArea(height, 0, height.size() - 1);
    }
    
    int maxArea(vector<int> height, int begin, int end) {
        if (begin == end) {
            return height[begin];
        }
        
        int mid = begin + (end - begin) / 2;
        int mArea = maxArea(height, begin, mid);
        mArea = max(mArea, maxArea(height, mid + 1, end));
        mArea = max(mArea, maxCombineArea(height, begin, mid, end));
        
        return mArea;
    }    
    int maxCombineArea(vector<int> height, int begin, int mid, int end) {
        int maxArea = 0;
        int left = mid, right = mid + 1;
        int high = min(height[left], height[right]);
        
        while (left >= begin && right <= end) {
            high = min(high, min(height[left], height[right]));
            maxArea = max(maxArea, (right - left + 1) * high);
            if (left == begin) {
                ++right;
            } else if (right == end) {
                --left;
            } else {
                if (height[left - 1] > height[right + 1]) {
                    --left;
                } else {
                    ++right;
                }
            }
        }
        
        return maxArea;
    }
};

 

posted @ 2017-05-14 21:14  Vincent丶丶  阅读(167)  评论(0编辑  收藏  举报