LeetCode-84. 柱状图中最大的矩形

84. 柱状图中最大的矩形

难度困难294收藏分享切换为英文关注

通过次数

15,951

提交次数

42,724

题目描述

评论 (106)

题解(33)New

提交记录

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

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

 

LeetCode-84. 柱状图中最大的矩形_第1张图片

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

 

LeetCode-84. 柱状图中最大的矩形_第2张图片

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

 

示例:

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

 

 

个人觉得真的很难,暴力的方法仔细想想可以出来,但是像使用单调栈这种方法去优化。实在是没有思考出来,看别人的解析也看了很久,主要针对弹出栈之后才继续进行的 i - m_stack.top()-1 的计算。

关于单调栈的解析附上此作者原文地址:https://blog.csdn.net/Zolewit/article/details/88863970

个人认为讲的最好的了,从为什么要使用单调栈,到针对单调栈的宽度的求法,解析的很清楚...我重新写也不一定能讲的如此作者这么好!

 

暴力1:(会超时)

int max(int a, int b){
    if(a>b){
        return a;
    }else{
        return b;
    }
}

class Solution {
public:

    /* 去重 */
    vector unique_by_hands(vector& heights){
        vector h_hash(heights);
        sort(h_hash.begin(),h_hash.end());
        vector::iterator iter = unique(h_hash.begin(),h_hash.end());
        h_hash.erase(iter,h_hash.end());
        return h_hash;
    }

    int largestRectangleArea(vector& heights) {
        vector h_hash = unique_by_hands(heights);

        /* 最大面积 */
        int max_area = 0;
        vector::iterator it = h_hash.begin();
        while(it!=h_hash.end()){
            int width = 0;

            /* 最大宽度 */
            int max_width = 1;
            int height = *it;
            vector::iterator jt = heights.begin();
            while(jt!=heights.end()){
                if(*jt>=height){
                    width++;
                }else{
                    max_width = max(width,max_width);
                    width = 0;
                }
                jt++;
            }
            it++;

            max_width = max(width,max_width);
            max_area = max(max_area, height*max_width);
        }

        return max_area;
    }
};

暴力2:(会超时)


class Solution {
public:
	int max_area = 0;
    int largestRectangleArea(vector& heights){
		vector::iterator it = heights.begin();
		while (it != heights.end()) {
			int left_width = 0;
			/* 左右扩散,记录当前值 */
			vector::iterator desc_it = it;
			vector::iterator asc_it = it;
			while (1) {
				if (*desc_it < *it || desc_it == heights.begin()) {
					if (*desc_it >= *it) {
						left_width++;
					}
					break;
				}
				desc_it--;
				left_width++;
			}
			cout << "left width : " << left_width << " ";
			
			/* 算过一次自己不用再算 */
			int right_width = -1;
			while (1) {
				if (*asc_it < *it || (asc_it== heights.end()-1)) {
					if (*asc_it >= *it) {
						right_width++;
					}
					break;
				}
				right_width++;
				asc_it++;
			}
			cout << "right width : " << right_width << " ";
			cout << "width : " << left_width + right_width << endl;

			/* 计算最大面积 */
			int area = (left_width + right_width)*(*it);
			max_area = max(area, max_area);

			it++;
		}
		return max_area;
	}

private:
	int max(int a, int b) {
		if (a >= b) {
			return a;
		}
		else {
			return b;
		}
	}

};

 

单调栈:(ac,个人觉得比上文作者写的更容易理解一点,我这里将栈为空和不为空两种情况分开来进行讨论)

#include 
#include 
#include 
#include 
using namespace std;

class Solution {
public:
    stack m_stack;
    int max_area = 0;

    int largestRectangleArea(vector& heights) {
        heights.push_back(0);
        for(int i=0;i m_arr = {2,1,5,6,2,3};
    //vector m_arr = {0};
    //vector m_arr = {2,1,2};

    Solution *p = new Solution();
    int answer = p->largestRectangleArea(m_arr);
    cout<<"answer:"<

 

你可能感兴趣的:(算法,C++,LeetCode)