Leetcode#84 Largest Rectangle in Histogram - Go语言中文社区

Leetcode#84 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.
在这里插入图片描述
The largest rectangle is shown in the shaded area, which has area = 10 unit.

解法

解法一

考虑到最大面积的矩形高度一定跟某个条一样高,所以挨个枚举每个条,看其向左、向右最多能延伸到多远。在计算左右边界时,可以借助之前计算过的结果迭代(类似动归的感觉)优化以减少时间复杂度,这应该算是唯一的难点了。总的来说,向左一遍,向右一遍,整体求面积再一遍,一共需要3次遍历,时间复杂度是O(n)。
左右扫描法非常直观。
来自:https://www.cnblogs.com/boring09/p/4231906.html

代码:

class Solution {
public:
	int largestRectangleArea(vector<int>& hei) {

		int N = hei.size();
		if (N <= 0)
			return 0;
		vector<int> rt(hei.size());
		vector<int> lf(hei.size());

		for (int j = N - 1; j >= 0; --j) {
			rt[j] = 1;
			while (j + rt[j] < N && hei[j]>0 && hei[j + rt[j]] >= hei[j]) {
				rt[j] += rt[j + rt[j]];
			}
		}

		for (int j = 0; j < N; ++j) {
			lf[j] = 1;
			while (j - lf[j] >= 0 && hei[j]>0 && hei[j - lf[j]] >= hei[j]) {
				lf[j] += lf[j - lf[j]];
			}
		}
		int ans = 0;
		for (int j = 0; j < N; j++) {
			ans = max(ans, (rt[j] + lf[j] - 1)*hei[j]);
		}
		return ans;
	}
};

下面给出 复杂度证明
我们只看第一遍从右往左遍历这个过程,
假说是第 n/k 处(k可以是小数) 很辛苦一个一个往右找了 n/p (1/k + 1/p <=1 )个点,那么此时

  • [0, n/k]里大于等于hei[n/k]的点,其复杂度总和是 T(n/k)
  • [0, n/k]里小于hei[n/k]的点,其复杂度总和是 T(n/k)+ O((n-n/k) - n/p)
    • 相当于把[n/k, n/k+n/p]之间的点抹掉,而且对于后面那一串 n-n/k) - n/p个点,最多再往右边跳n-n/k) - n/p

鉴于 (n-n/k) - n/p >= 0, 因此 T(n/k)+ O((n-n/k) - n/p) > T(n/k),
所以对于 [0, n/k] 所有点的复杂度总和为: T(n/k)+ O((n-n/k) - n/p)
此时有:T(n) = T(n/k)+ O((n-n/k) - n/p) + O(n-n/k) + O(n/p) = T(n/k)+ O(n-n/k) ==> T(n) = O(n)
当然上面这个式子成立还应该再加一个前提假设:第 n/k 处的点是最右边那个往右跳且跳的次数达到了O(n)量级的。O(n)量级已经是最大的可能。如果是其他关于n的函数,那么最终复杂度必然小于O(n)。

解法二

参考:https://www.cnblogs.com/boring09/p/4231906.html

版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/u013263974/article/details/100643363
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢