【LeetCode】84. Largest Rectangle in Histogram(C++)

地址:https://leetcode.com/problems/largest-rectangle-in-histogram/

题目:

Given n n 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.

Example:

Input: [2,1,5,6,2,3]
Output: 10

理解:

给了一个柱状图,要求其能构成的矩形的最大面积。构成的矩形不能超过其起始任意一个矩形的高。也就是说,矩形的高是受限于高度最矮的矩形的。

觉得这个题和Container With Most Water有一点点相似。不过区别在于那个题,容量只受限于左右两个边中较低的,而本题中,是受限于一个区域中最矮的矩形。

实现1:

参考:Largest Rectangular Area in a Histogram
借助了一个栈,保存比当前矮的位置。i为工作指针
如果heights[i]大于等于栈顶,就把其入栈;
如果小于,则依次弹出栈顶,并用弹出的值当作当前矩形的高,i-1为矩形的右边界,而把新的栈顶+1作为左边界。如果栈为空,就说明没有更矮的了,直接把0作为左边界就可以了。

class Solution {
public:
	int largestRectangleArea(vector<int>& heights) {
		int maxArea = 0;
		stack<int> stk;
		for (int i = 0; i <= heights.size(); i++) {
			int h = (i == heights.size() ? 0 : heights[i]);
			if (stk.empty() || h >= heights[stk.top()])
				stk.push(i);
			else {
				int heightIndex = stk.top();
				stk.pop();
				int r = i - 1;
				int l = stk.empty() ? 0 : stk.top()+1;
				int width = r - l + 1;
				maxArea = max(maxArea, heights[heightIndex] * width);
				i--;
			}
		}
		return maxArea;
	}
};

实现2:

记录每个位置左边和右边比当前位置低的位置,则矩形仍然由左右所夹区域和当前矩形的高确定。这种实现更容易理解一些。

class Solution {
public:
	int largestRectangleArea(vector<int>& heights) {
		int maxArea = 0;
		if (heights.empty()) return 0;
		vector<int> left(heights.size()), right(heights.size());
		left[0] = -1;
		right[heights.size() - 1] = heights.size();
		for (int j = 1; j < heights.size(); j++) {
			int p = j - 1;
			while (p >= 0 && heights[p] >= heights[j])
				p = left[p];
			left[j] = p;
		}
		for (int j = heights.size() - 2; j >= 0; j--) {
			int p = j + 1;
			while (p < heights.size() && heights[p] >= heights[j])
				p = right[p];
			right[j] = p;
		}
		for (int j = 0; j < heights.size(); j++) {
			maxArea = max(maxArea, heights[j] * (right[j] - left[j] - 1));
		}
		return maxArea;
	}
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值