在柱状图中找最大矩形——O(n)时间复杂度java实现

在柱状图中找最大矩形——O(n)时间复杂度java实现

 ZZ:http://blog.csdn.net/xybsos/article/details/8049048

   具体题目如下:给一组非负的整数来表示一个柱状图,设计一个算法获得柱状图中最大矩形的面积。比如,输入如下数据:2,1,4,5,1,3,3 ,其中每个数表示一个柱状条的高度,柱状条的宽度为默认值1,则计算得最大矩形的面积为8。

    思路:使用一个栈来保存输入柱状条,每个柱状条包含两个信息:(1)柱状条的高度(height);(2)柱状条的x坐标(index) 。数组中的柱状条按序准备入栈,入栈的条件:当入栈元素e的高度>=栈顶元素的高度时,元素e入栈;否则,将栈顶元素出栈,同时更新最大矩形maxValue的值。

    更新maxValue的算法如下:

    1. 计算以当前栈顶元素的高度为宽度的矩形的面积:tmpValue = topElement.height * (e.index - topElement.index);

    2. 更新maxValue: maxValue = (maxValue > tmpValue) ? maxValue : tmpValue;

    所有元素入栈完毕,将栈中剩余的元素依次出栈,同时按照相同的思路更新maxValue的值。

java实现:

 

import java.util.ArrayList;
import java.util.List;
import java.util.Stack;

public class MaxRectangle {

    // 使用栈来保存每个柱状条,当当前准备入栈的柱状条的高度小于当前栈顶的柱状条高度时,先让栈顶元素出栈,同时计算最大的矩形大小
    public int maxRectangleValue(int[] array) {
        if (array == null || array.length <= 0)
            return -1;
        int maxValue = 0;
        List<Element> inputList = new ArrayList<Element>();
        int len = array.length;
        for (int i = 0; i < len; i++) {
            Element element = new Element(array[i], i);
            inputList.add(element);
        }
        // 开始入栈操作
        Stack<Element> stack = new Stack<Element>();
        for (Element e : inputList) {
            if (stack.empty())
                stack.add(e);
            else {
                while (e.height < stack.peek().height) { // 出栈,并计算最大矩形大小
                    Element topElement = stack.pop();
                    int tmpValue = topElement.height * (e.index - topElement.index); // height * width
                    if (tmpValue > maxValue)
                        maxValue = tmpValue;
                    if (stack.empty())
                        break;
                }
                // 进栈
                stack.add(e);
            }
        }
        // 将堆栈中包含的所有元素出栈,同时更新最大的矩形大小
        while (!stack.empty()) {
            Element topElement = stack.pop();
            int tmpValue = topElement.height * ((len - 1) - topElement.index + 1); // height * width
            if (tmpValue > maxValue)
                maxValue = tmpValue;
        }
        return maxValue;
    }
    
    public static void main(String[] args) {
        int[] array = {2,1,4,5,1,3,3};
        MaxRectangle mr = new MaxRectangle();
        System.out.println(mr.maxRectangleValue(array));
    }
}

class Element {
    public int height; // 每一个柱状条的高度(宽度为1)
    public int index; // 每个柱状条的x坐标值,代表它们出现的相对次序
    public Element(int height, int index) {
        this.height = height;
        this.index = index;
    }
}

 

算法分析:

 

    所有数组元素需要一次进栈和一次出栈,所以总的时间复杂度为:O(n)

 

posted @ 2012-10-18 10:25  技术收集专用  阅读(912)  评论(0编辑  收藏  举报