Leetcode 84 柱状图中最大的面积

给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。

求在该柱状图中,能够勾勒出来的矩形的最大面积。

以上是柱状图的示例,其中每个柱子的宽度为 1,给定的高度为 [2,1,5,6,2,3]

图中阴影部分为所能勾勒出的最大矩形面积,其面积为 10 个单位。

示例:

输入: [2,1,5,6,2,3]
输出: 10

一开始看到后想也没想就用暴力解法去做 方法就是当宽为1时,即比较每个数组中最大的那个元素值,宽为2时,比较相邻两个元素之间取最小的值,遍历完一边后找到相邻元素之间最小的值的集合中最大的值,宽为3的话也是以此类推,比较相邻三个元素之间取最小值然后取集合中最大的值 

代码如下:

class Solution {
public:
    int largestRectangleArea(vector<int>& heights) {
        int size=heights.size();
        if(size==0)return 0;
        if(size==1)return heights[0];
        int maxres=INT_MIN;
        int minres=INT_MIN;
        vector<int>res;
        vector<int>first;
        int count=1;
        for(int i=0;i<size;i++){
            first.push_back(heights[i]);
        }
        sort(first.begin(),first.end());
        maxres=first[first.size()-1];            
        for(int i=1;i<size;i++){
            count++;  
            res=fun(heights);
            heights.clear();
            for(int k=0;k<res.size();k++){     
                    heights.push_back(res[k]);
             }      
            sort(res.begin(),res.end());
            minres=res[res.size()-1]; 
            maxres=max(maxres,count*minres);                         
            
        }
        return maxres;
        
    }
            
        
    
    vector<int> fun(vector<int>& temp){
        
        vector<int>res;
        if(temp.size()==1)res.push_back(temp[0]);
        for(int i=1;i<temp.size();i++){
            if(temp[i]>temp[i-1]){
                res.push_back(temp[i-1]);
            }else{
                res.push_back(temp[i]);
            }
        }
        return res;
    }
};

然后一跑,果然 测试到最后2个例子就超出时间限制了 时间复杂度为O(n的2次方)

然后就去网上查阅了一下方法 用到了单调栈于是记录一下方法

思路大概就是这样:如果我们的数组是升序的话 例如:5 6 7 8 9 那么我们解的集合就是从5*5,6*4,7*3,8*2,9*1中去取

所以我们为了往升序的数组靠近 就用到单调栈,通过比较当前栈顶元素值和当前数组heights[i]的大小,如果栈顶元素小于当前数组heights[i]就加入栈中,否则将栈顶元素移除pop,并且记录此时的矩形面积=移除的元素*移除的个数。移除后继续与栈顶元素比较依次循环直至栈顶元素小于当前数组heights[i]然后加入栈中。

例如题目中 :2 1 5 6 2 3

首先我们将0加入栈中 不会引发错误

然后① 2>0 直接加入栈顶 继续

② 1<栈顶元素2 所以将2移除栈 将1加入栈中 此时记录面积2 *1 =2

③5>1 直接加入栈中  1 5

④6>5 直接加入栈中 1 5 6

⑤2<栈顶元素6 将6移除 此时记录面积为6*1 继续 2<栈顶元素5 将5移除 此时记录面积为5*2 继续 2>1 所以将2加入栈中 1 2

⑥3>2 直接加入栈中 此时栈中元素 1 2 3 通过一开始那个升序方法求得 这个的面积集合有1*3,2*2 ,3*1

⑦我们只要将上面最大的面积取出来即是答案

代码如下:

 
class Solution {
public:
    int largestRectangleArea(vector<int>& heights) {
        int n = heights.size();
		// Exceptional Case: 
		if(n == 0){
			return 0;
		}
		if(n == 1){
			return heights[0];
		}
		// insert 0 height
		heights.push_back(0);
		stack<int> st;
		int ans = 0;
		for(int i = 0; i <= n; i++){
			if(st.empty() || heights[i] >= heights[st.top()]){
				st.push(i);
			}
			else{
				int top = st.top();
				st.pop();
				int w = st.empty()? i: i - 1 - st.top();
				ans = max(ans, heights[top] * w);
				i--;
			}
		}
		return ans;
    }
};

猜你喜欢

转载自blog.csdn.net/wangjianxin97/article/details/84033500
今日推荐