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

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)

你可能感兴趣的:(ACM)