您的位置:首页 > 其它

ACM-直方图最大面积-Largest Rectangle in Histogram

2016-08-20 21:01 337 查看
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
.

题目链接:https://oj.leetcode.com/problems/largest-rectangle-in-histogram/

HOJ:http://www.acmerblog.com/hdu-1506-Largest-Rectangle-in-a-Histogram-2063.html

此题也经典的一个题,就是求出一个最大的矩形面积。

解法一

使用动态规划,用left[i]表示第i个柱子可以最多向左延伸至第left[i]个柱子,形成一个矩形,right[i]则表示向右延伸。遍历两次,分别计算出这两个数组。

再遍历一次,即可求出所有的柱子可以形成的最大的矩形面积。为了减少边界的判断,可以使用哨兵,在两端添加两个柱子高度都为-1.

01
//============================================================================
02
//
Name: MaxRectagle.java
03
//
Author  : GaoTong
04
//
Date: 2014/9/5
05
//
Copyright   : www.acmerblog.com
06
//============================================================================
07
public
class
MaxRectagle
{
08
public
static
void
main(String
args[]){
09
int
height[]
= {
2
,
1
,
5
,
6
,
2
,
3
};
10
int
ans
= getMaxRectangle(height);
11
System.out.println(ans);
12
}
13
14
public
static
int
getMaxRectangle
(
int
heights[]){
15
int
ans
=
0
;
16
int
n
= heights.length;
17
int
left[]
=
new
int
[n+
1
];
18
int
right[]
=
new
int
[n+
1
];
19
processLR(heights,
left, right);
20
for
(
int
i=
1
;
i<=n; i++){
21
int
tmp
= (right[i]-left[i]+
1
)
* heights[i-
1
];
22
if
(
ans < tmp)
23
ans
=tmp;
24
}
25
return
ans;
26
}
27
28
public
static
void
processLR(
int
heights[],
int
left[],
int
right[]){
29
int
n
= heights.length;
30
//用临时数组,设置两个哨兵
31
int
tempArr[]
=
new
int
[n+
2
];
32
tempArr[
0
]
= -
1
;
33
for
(
int
i=
1
;
i<=n; i++) tempArr[i] = heights[i-
1
];
34
tempArr[tempArr.length-
1
]
= -
1
;
35
36
for
(
int
i=
1
;
i<=n; i++){
37
int
k
= i;
38
while
(
tempArr[i] <= tempArr[k-
1
])
39
k
= left[k-
1
];
40
left[i]
= k;
41
}
42
43
for
(
int
i=n;
i>
0
;
i--){
44
int
k
= i;
45
while
(
tempArr[i] <= tempArr[k+
1
])
46
 
k
= right[k+
1
];
47
right[i]
= k;
48
}
49
}
50
}
算法的时间复杂度为 O(n)。 再求left[]和right[]时,虽然里面有while循环,但可以保证复杂度为O(n)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: