刷题84. Largest Rectangle in Histogram

I, entitled Description

Title 84. Largest Rectangle in Histogram, to form a histogram, find the largest area of ​​the graph given n non-negative integers (a width of each column 1). Difficulty of the subject is Hard!

Second, my answer

This is a look easy, but doing it is easy to mistake the title . I started to use the word "digging Law", unfortunately, always Time Limit Exceeded . After 10 sub-optimal, or difficult to see.

class Solution{
    public:
        int largestRectangleArea(vector<int>& heights){
            int len = heights.size();
            if(len<1) return 0;
            if(len==1) return heights[0];
            int result = 0;
            int start=len-1,end=0;
            int cnt = 0,sum=0;
            int min;

            while(1){
                min = INT_MAX;
                for(int i=0;i<len;i++){
                    if(heights[i]>0 && heights[i]<min){
                        min = heights[i];
                    }
                }

                //找到第1个正的 
                while(end<len && heights[end]<=0){
                    end++;
                }
                while(start>0 && heights[start]<=0){
                    start--;
                }
                if(start==end){
                    sum = heights[start];
                    if(sum>result) result = sum;
                    break;
                }else if(end>start) {
                    break;
                }
                    
                sum = 0;
                cnt = 0;
                //一次遍历,求大于0的连续长度  最大值 
                while(end<len){
                    cnt = 0;
                    sum = 0;
                    while(end<len && heights[end]>=min){
                        if(heights[end]==min) heights[end] = 0;
                        cnt++;
                        end++;
                    }
                    sum = cnt * min;
                    if(sum>result) result = sum;
                    if(end<len) end++;
                }
                end = 0;
                start = len-1;
            }
            return result;
        }
};

performance:

Runtime: 1536 ms, faster than 4.53% of C++ online submissions for Largest Rectangle in Histogram.
Memory Usage: 9.9 MB, less than 94.29% of C++ online submissions for Largest Rectangle in Histogram.

The method can also think of violence calculations, performance is also similar:

class Solution{
    public:
        //brute force
        int largestRectangleArea(vector<int>& heights){
            int len = heights.size();
            if(len<1) return 0;
            if(len==1) return heights[0];
            int result = 0;
            bool allthesame = true;
            for(int i=0;i<len-1;i++){
                if(heights[i]!=heights[i+1]){
                    allthesame = false;
                }
            }
            if(allthesame){
                return heights[0]*len;
            }
            
            for(int i=0;i<len;i++){
                int minHeight = INT_MAX;
                for(int j=i;j<len;j++){
                    minHeight = min(minHeight,heights[j]);
                    result = max(result,minHeight * (j-i+1));
                }
            }
            
            return result;
        }
};
Runtime: 1040 ms, faster than 5.03% of C++ online submissions for Largest Rectangle in Histogram.
Memory Usage: 10 MB, less than 94.29% of C++ online submissions for Largest Rectangle in Histogram.

Third, the optimization measures

Stack with a monotonically increasing method, as follows:

class Solution{
    public:
        //单调递增栈 
        int largestRectangleArea(vector<int>& heights){
            int result = 0;
            stack<int> st;
            st.push(-1);//-1 放进栈的顶部来表示开始

            //按照从左到右的顺序,我们不断将柱子的序号放进栈中,直到 heights[i]<heights[st.top]
            //将栈中的序号弹出,直到heights[stack[j]]≤heights[i]
            for(int i=0;i<heights.size();i++){
                while(st.top()!=-1 && heights[i]<heights[st.top()]){
                    int h = st.top();
                    st.pop();
                    result = max(result,heights[h]*(i - st.top() -1));
                }
                st.push(i);
            } 
            
            // 遍历完了,但是没计算完
            while(st.top() != -1){
                int h = st.top();
                st.pop();
                int len = heights.size() - st.top() -1;
                result = max(result,heights[h]*len);
            }
            
            return result;
        }
};
Runtime: 16 ms, faster than 53.51% of C++ online submissions for Largest Rectangle in Histogram.
Memory Usage: 10.4 MB, less than 91.43% of C++ online submissions for Largest Rectangle in Histogram.

Continue to optimize:

class Solution{
    public:
        //单调递增栈 ,借用i当栈 
        int largestRectangleArea(vector<int>& heights){
            int result = 0;
            int len, wid;
            for (int i = 0; i < heights.size(); i++) {
                if(i != heights.size() - 1 && heights[i] <= heights[i + 1]) continue;   //这一步的判断很玄妙
                wid = heights[i];
                for (int j = i; j >= 0; j--) {
                    len = i - j + 1;
                    wid = min(wid, heights[j]);
                    result = max(result, len * wid);
                }
            }
            
            return result;
        }
};
Runtime: 12 ms, faster than 89.13% of C++ online submissions for Largest Rectangle in Histogram.
Memory Usage: 10 MB, less than 94.29% of C++ online submissions for Largest Rectangle in Histogram.
Next challenges:

Guess you like

Origin www.cnblogs.com/siweihz/p/12259691.html