柱状图中的最大矩形面积(leetcode 84)

1、题目描述

    给定n个非负整数表示直方图的条形高度,其中每个条形的宽度为1,找到直方图中最大矩形的区域。

        柱状图中的最大矩形面积(leetcode 84)_第1张图片                     柱状图中的最大矩形面积(leetcode 84)_第2张图片

    

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

2、解题思路

(1)暴力破解

    找出直方图中的所有矩形,然后求最大的面积,这种方法的时间复杂度为O(n^2),空间复杂度为O(1)。代码如下:

    int largestRectangleArea(vector& heights) {
        if (heights.size() == 0)
        {
            return 0;
        }
        int max = heights[0];
        for (int i = 0; i < heights.size(); i++)
        {
            int area;
            for (int j = i; j >= 0; j--)
            {
                area = (i - j + 1) * MinValue(heights, j, i);            
                if (max < area)
                {
                    max = area;
                }
            }
        }
        return max;
    }
    
    int MinValue(vector& arr, int start, int end)
    {
        int min = INT32_MAX;
        for (int i = start; i <= end; i++)
        {
            if (arr[i] < min)
            {
                min = arr[i];
            }
        }
        return min;
    }

(2)使用栈来解决,空间换时间

    矩形面积的计算公式为 底*高。对于直方图中的每个矩形’x’,以该矩形的高度为高(因为在直方图中最大矩形的高必然是某个单独矩形高),然后计算出最大矩形面积。因此接下来的问题是,若以某个矩形的高度为高,那么最终矩形的左边界右边界在哪里?确定两个边界后就可以得到宽度,最终计算出面积。

    我们从左向右遍历每个矩形,并通过一个栈来存储这些矩形高度在输入数组中的索引。每个索引仅压入栈中一次。当输入的矩形高度小于栈顶索引指向的矩形高度时,那么栈顶索引将会被弹出,然后计算该索引指向的矩形的面积,其中矩形面积的高为弹出的索引指向的矩形条的高。现在得到了高,接下来得到左右边界后便可计算出宽度。由于当前输入的矩形i的高度小于栈顶索引指向的矩形,那么以栈顶索引指向矩形为高的矩形右边界为 i。而在当前栈中若非空,那么栈中索引指向的矩形条的高度一定是小于等于弹出的索引指向的矩形的高度,因此左边界就确定了。(当有多个连续的高度一样的矩形条时,计算最后一个出栈的矩形时会得到最终的面积)。这种方法采用空间换时间,时间复杂度为O(n),空间复杂度也为O(n)。代码如下:

    int largestRectangleArea(vector& heights) {
        stack temp;
        int maxarea = 0;
        int i = 0;
        for (i = 0; i < heights.size();)
        {
            if (temp.empty() || heights[temp.top()] < heights[i])
            {
                temp.push(i++);
            }
            else
            {
                int top = temp.top();
                temp.pop();
                int area = heights[top] * (temp.empty() ? i : i - temp.top() - 1);

                if (maxarea < area)
                {
                    maxarea = area;
                }

            }
        }

        while (!temp.empty())
        {
            int top = temp.top();
            temp.pop();
            int area = heights[top] * (temp.empty() ? i : i - temp.top() - 1);

            if (maxarea < area)
            {
                maxarea = area;
            }
        }
        return maxarea;
    }

 

你可能感兴趣的:(算法)