84. Largest Rectangle in Histogram
Total Accepted: 57808 Total Submissions: 239940 Difficulty: Hard
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.
Above is a histogram where width of each bar is 1, given height = [2,1,5,6,2,3]
.
The largest rectangle is shown in the shaded area, which has area = 10
unit.
For example,
Given heights = [2,1,5,6,2,3]
,
return 10
.
42. Trapping Rain Water
Total Accepted: 63876 Total Submissions: 199058 Difficulty: Hard
Given n non-negative integers representing an elevation map where the width of each bar is 1, compute how much water it is able to trap after raining.
For example,
Given [0,1,0,2,1,0,1,3,2,1,2,1]
, return 6
.
The above elevation map is represented by array [0,1,0,2,1,0,1,3,2,1,2,1]. In this case, 6 units of rain water (blue section) are being trapped. Thanks Marcos for contributing this image!
【分析】
这个题之前我在一次面试中曾被问及,当时没有给出好的解法,没想到出处在此。此题与【LeetCode】42. Trapping Rain Water有一定相似,但算法要难一些。
对于此题(84),最直观的思路就是列举所有可能的矩形组合,共有n(n+1)/2个组合,时间复杂度为O(n2),这样的"暴力解法"自然过不了大集合测试,超时是必然的。我在网上看到一个精妙的解法,但是并不直观,我根据其核心思想,自己写了一个C++的解法:
1、核心规律:当给定直方图高度为“升序”排列的时候,如[1,5,6,8],我们只需要比较1*4, 5*3, 6*2, 8*1的大小,找出最大值即可,一次遍历,O(n)即可完成;
2、异常处理:当给定的直方图出现局部“降序”排列时,如[2,3,1,5,6,8],由于heights[2]
3、对最后形成的“升序”序列求面积:若序列长度为N,面积分别为:heights[0]*N,heights[1]*(N-1),...,heights[N-1]*1;将这些面积与全局最大值比较,最后得到的最大面积为全局最大;
4、对于算法来说,合适的数据结构可以简化操作,根据上面分析,一种合适的数据结构是栈,利用栈可以很容完成上面的算法;
【解法及注释】
class Solution {
public:
int largestRectangleArea(vector& heights)
{
if(heights.size()==0)return 0;//空输入处理
int maxArea=0;//存储最大面积
int count=0;//计数变量,记录当前入栈数据个数
stack stk;//定义一个辅助栈
int i=0;
while(iheights[i])//求取降序点前的升序部分直方图可组合的矩形面积,k约束循环次数
{
k++;
int top=stk.top();//比降序点大的栈顶元素依次出栈并求取面积,这里是个技巧,可以避免不必要的计算
stk.pop();
maxArea=Max(maxArea,top*k);
}
while(k--)//将降序点前面比降序点数值大的部分“铲平”,置为降序点的数值,并入栈
{
stk.push(heights[i]);
}
}
}
int count1=0;
while(count1b?a:b;}
};
【运行结果】