leetcode之Largest Rectangle in Histogram

原题如下:

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 height = [2,1,5,6,2,3],
return 10.

这道题确实有一定的难度,但其实O(n *n)的方法还是应该能够想到的,即计算两两之间的最大面积,在计算过程中需要利用动态规划的方法求解两两之间的最小高度,因此需要一个数组来保存这些高度值。另外在计算的过程中,当发现两两节点中第一个节点是短板时(即以它为高度,以最大宽度计算的面积都小于最大面积),可以略过此遍历。

 int largestRectangleArea(vector<int> &height) {
		int len = height.size();
		if(len == 0 )
			return 0;
		if(len == 1)
			return height[0];
		vector<int>min(len,0);
		int maxArea = 0;
		for(int i = 0; i < len; i++){  //依次遍历数组元素i,计算i与其后节点j之间的最大面积
			if(height[i] * (len - i) <= maxArea) //  如果以height[i]为高度计算其后整个的面积都小于maxArea,那么以i为起点的可以略过
				continue;
			for(int j = i; j < len; j++ ){
			    if(j == i)
					min[j] = height[i];
				else if(height[j] < min[j - 1])
					min[j] = height[j];
				else
					min[j] = min[j - 1];
				if(j != len - 1 && height[j] < height[j + 1])
					continue;
				if(min[j] * (j - i + 1) > maxArea)
					maxArea = min[j] *(j - i + 1);
			}
		}
		return maxArea;

    }
另外还有一种改进的方法,在这篇博文中对改进的方法进行了详细的介绍: http://www.cnblogs.com/lichen782/p/leetcode_Largest_Rectangle_in_Histogram.html,这种方法的大体思路如下:首先在原数组的末尾添加元素0作为结束符(其作用在算法中体现),另外需要一个栈来保存递增高度的下标,在遍历原数组的过程中,当栈为空或栈中元素下标所在的元素值的高度小于当前遍历的下标的高度,则将当前遍历的下标入栈,否则,计算当前栈中栈顶元素与比当前元素值大的下标之间的最大面积,这里需要注意的是以栈中为下标的元素值是递增的,所以在依次出栈计算时其高度是不断减小的,该高度所表示的范围是其栈中前一个节点之后的范围,所以在计算其宽度时是i - 1 (i - 1为栈顶元素下标)减去其下一个元素的下标,所以需要在获得高度值int t = s.top();之后先出栈以获得宽度(其栈中下一个元素)再计算面积,所以需要对栈为空时进行特殊处理,而且需要注意栈中元素下标值是不连续的。还是借助上述博客中的图比较容易理解,另外需要注意在上述博客中有一个图存在一些小错误。

int largestRectangleArea(vector<int> &height) {
		int len = height.size();
		if(len == 0)
			return 0;
		if(len == 1)
			return height[0];
		stack<int>s; //保存之前的下标
		int maxArea = 0;
		height.push_back(0);
		len++;
		int i = 0;
		while(i < len){
			if(s.empty() || height[s.top()] <= height[i])
				s.push(i++);
			else{				
					int t = s.top();
					s.pop();
					maxArea = max(maxArea,height[t] *(s.empty()?i:(i - 1 - s.top())));	
				   
					
				}				
			
		}
		return maxArea;
	}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值