Skip to content

Commit

Permalink
added 114. Largest Rectangle in Histogram
Browse files Browse the repository at this point in the history
  • Loading branch information
pezy committed Feb 9, 2015
1 parent 7770972 commit 6de2099
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 0 deletions.
53 changes: 53 additions & 0 deletions 114. Largest Rectangle in Histogram/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@

_ _
| | _ _ | |
| | | |_| | | |
| | |*|*|*| | |
| |_|*|*|*| | |
| | |*|*|*|_| |
|_|_|_|_|_|_|_|
6 2 5 4 5 1 6
^ ^ ^
0 1 2 3 4 5 6

如图所示,很直观:`3 * 4 == 12`.首先思考,我们是如何得到最大面积 12 的?

我们发现,要计算 Largest Rectangle ,关键是找**短板**,如我们挑选的 4,类似的还有哪些呢?列个表:

|min_height|rectangle|area|
|:--------:|:-------:|:--:|
| 2 | 0 -> 4 | 2*5|
| 4 | 2 -> 4 | 4*3|
| 1 | 0 -> 6 | 1*6|

最终很明显,area 最大的即为中间那行,结果为 12.

再进一步思考:

1. 短板是如何摘出来的?这个很显然,是衰减发生的时候出现的。如 6->2, 5->4, 5->1.
2. 短板的周期如何得出?细致观察后,发现是短板之间的升降分割出的。如 2->4:(2), 2->1, 4->1:(4), 2 和 4 便是分隔符。

好了,现在发现了规律,但如何准确找到所需的数据结构呢?

我们的第一个目的显然是要找出短板,短板的条件是:

height[i] < height[i-1]

貌似迭代一遍即可,但短板的周期分隔点如何得出呢?我们不仅要找出短板,还需要留下短板以及短板的 index, 以便寻找分隔符。

看来我们需要一把筛子,筛掉不符合短板条件的,留下短板。

****非常符合筛子的特性,不管三七二十一,push 进去,不符合则 pop 出来。

```cpp
int max_area = 0, i = 0, size = height.size();
for (stack<int> stk; i<size || !stk.empty(); ) { // 这个的 for 循环在二叉树的题目里经常出现(DFS)
if (stk.empty() || (i != size && height[stk.top()] <= height[i])) stk.push(i++); // 不是短板,则 push
else {
int tp = stk.top(); stk.pop();
max_area = std::max(max_area, height[tp] * (stk.empty() ? i : i-stk.top()-1));
}
}
```

基本逻辑很简单,5 行结束。
18 changes: 18 additions & 0 deletions 114. Largest Rectangle in Histogram/TEST.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#define CATCH_CONFIG_MAIN
#include "../Catch/single_include/catch.hpp"
#include "solution.h"

TEST_CASE("Largest Rectangle in Histogram", "[largestRectangleArea]")
{
Solution s;
SECTION( "common1" )
{
std::vector<int> height{6, 2, 5, 4, 5, 1, 6};
REQUIRE( s.largestRectangleArea(height) == 12 );
}
SECTION( "common2" )
{
std::vector<int> height{2, 1, 5, 6, 2, 3};
REQUIRE( s.largestRectangleArea(height) == 10 );
}
}
20 changes: 20 additions & 0 deletions 114. Largest Rectangle in Histogram/solution.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#include <vector>
using std::vector;
#include <stack>
using std::stack;
#include <algorithm>
using std::max;

class Solution {
public:
int largestRectangleArea(vector<int> &height) {
int max_area = 0, i = 0, size = height.size();
for (stack<int> stk; i<size || !stk.empty(); )
if (stk.empty() || (i != size && height[stk.top()] <= height[i])) stk.push(i++);
else {
int tp = stk.top(); stk.pop();
max_area = max(max_area, height[tp] * (stk.empty() ? i : i-stk.top()-1));
}
return max_area;
}
};

0 comments on commit 6de2099

Please sign in to comment.