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
.
SOLUTION 1:
http://fisherlei.blogspot.com/2012/12/leetcode-largest-rectangle-in-histogram.html
使用遞增棧來處理。每次比較棧頂與當前元素。如果當前元素小於棧頂元素,則入站,否則合並現有棧,直至棧頂元素小於當前元素。結尾入站元素0,重復合並一次。
1. 當遇到一個違反遞增關系的元素時,例如:
2, 1, 5, 6, 2, 3
(1). S: 2
(2). S: 2 新的元素1比2要小,表示Index = 0的這個直方圖的右邊界到達了,我們可以計算以它高度的最大直方。那么這個寬度如何計算呢?
i = 1, 而2彈出后,棧為空,寬度是從i到最左邊(因為這是一個遞增棧,如果現在棧為空,表示我們取出的當前直方是最低的直方,它的寬度可以一直延展到最左邊。)
假如棧不為空,則寬度是 i - s.peek() - 1 (因為要減去s.peek()這個直方本身,它比s.pop()要低,阻止了s.pop()這個直方向左邊延展)
2 彈出后,棧為空。
(3). S: 1, 5, 6(這三個是連續遞增,就讓它們一直入棧)
(4). S: 1, 5, 6 現在我們遇到2, 6 出棧,它的寬度是6本身(i - 5所在的索引- 1)。5出棧,寬度是i - 1所在的索引 - 1
(5). 因為2比1要高,所以我們停止計算直方,把2繼續入棧。然后3入棧。
(6). 這時index = len. 我們直接到第二個分支,把1, 2, 3 這三個直方計算了。
(7). 棧為空,index = len 會入棧,然后index++ 越界,下一次就退出了。這里我們不可以把index < len 放在第一個判斷的前面來判斷,因為這樣的話,當index = len,
會直接再進入第二個分支,引發越界錯誤。其實我們就是假設在整個直方的最后存在一個height = 0的直方,所以我們要在一直計算到Index = len為止。而且因為它高度為0比誰都要低,所以可以把這個索引直接入棧。
View Code
GITHUB:
https://github.com/yuzhangcmu/LeetCode_algorithm/blob/master/array/LargestRectangleArea.java