Largest Rectangle in Histogram

Question:

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.

Analysis:

When solving this problem, the straightforward approach is to consider all possible cases, i.e., we begin with the ith rectangle, and then enumerate the remaining rectangles after the ith rectangle, each time, we need to compare the area with the maximum area. The time complexity is O(n^2).

public static int largestRectangleArea(int[] height) {
    if (height == null || height.length <= 0) return 0;
    int maxArea = 0;
    for (int i = 0; i < height.length; i++) {
        int minHeight = height[i];
        // we need to begin with i, otherwise, we can not pass the test case
        // in which the rectangle array is like [5, 0, 5, 0]
        for (int j = i; j < height.length; j++) {
            if (height[j] < minHeight) {
                minHeight = height[j];
            }
            int tempArea = minHeight * (j - i + 1);
            if (tempArea > maxArea) {
                maxArea = tempArea;
            }
        }
    }
    return maxArea;
}

Actually, we can decrease the complexity by using stack to keep track of the height and start indexes. Compare the current height with previous one.

Case 1: current > previous (top of height stack)
Push current height and index as candidate rectangle start position.

Case 2: current = previous
Ignore.

Case 3: current < previous
Need keep popping out previous heights, and compute the candidate rectangle with height and width (current index - previous index). Push the height and index to stacks.

(Note: it is better use another different example to walk through the steps, and you will understand it better).

public int largestRectangleArea(int[] height) {
    if (height == null || height.length == 0) return 0;
    
    int maxArea = 0;
    Stack<Integer> stackHeight = new Stack<Integer>();
    Stack<Integer> stackIndex = new Stack<Integer>();
    
    for (int i = 0; i < height.length; i++) {
    	//case 1
        if (stackHeight.isEmpty() || height[i] > stackHeight.peek()) {
            stackHeight.push(height[i]);
            stackIndex.push(i);
        } else if (height[i] < stackHeight.peek()) {
	        // case 3
	        int lastIndex = 0;
	        while (stackHeight.isEmpty() == false && height[i] < stackHeight.peek()) {
	        	lastIndex = stackIndex.pop();
	            int tempArea = stackHeight.pop() * (i - lastIndex);
	            if (maxArea < tempArea) {
	                maxArea = tempArea;
	            }
	        }
            stackHeight.push(height[i]);
            stackIndex.push(lastIndex);
        }
    }
    
    while(stackHeight.isEmpty() == false) {
        int tempArea = stackHeight.pop() * (height.length - stackIndex.pop());
        if (tempArea > maxArea) {
            maxArea = tempArea;
        }
    }
    return maxArea;
}
Reference:  http://www.youtube.com/watch?v=E5C5W6waHlo
http://www.leetcode.com





 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值