在柱状图中找最大矩形——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)