Largest Rectangle in Histogram

来源:互联网 发布:linux mv多个文件 编辑:程序博客网 时间:2024/06/05 07:29

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.

分析:http://www.geeksforgeeks.org/largest-rectangle-under-histogram/ 

其实这道题和longest valid parentheses是一样的,parentheses题目里只有当左括号是才压入stack,这里把一个peak的两边当做左括号和右括号。只有当增长时才压入栈(类比左括号压入栈)。不同的是括号问题里我们维护了一个start变量,因为当stack为空的时候不一定得到最大值(例如()())。而这里不用维护这个变量,stack为空了就说明之前的不用计入(比如说一个递降序列,stack push进去一个数马上又被pop出来,push的数也不用计算)

做法:

1. 扫描array,如果当前值比stack里的值大或者stack为空,直接push;如果当前值比栈顶元素小,那么pop栈顶元素,同时计算pop出来后,从新的栈顶元素到当前i的元素的面积:a) stack 不为空:(i - s.peek() - 1) * height[popIndex]。为什么是i-s.peek()-1,因为只计算pop掉的元素,从s.peek()到i的距离,所有还在stack里的不计算。b) stack为空,i*height[popIndex] 更新max area

2.array扫描了一遍,有可能stack里还有元素,比如最后是一连串的递增数列,那么我们就挨个pop掉栈顶,同时计算这个pop掉的面积: (i - s.peek() - 1) * height[popIndex] or i*height[popIndex] 。注意这时的i == height.lenght-1。意义为pop掉的值到最后的面积。

    public int largestRectangleArea(int[] height) {        int max = 0;        if (height.length < 1) {            return max;        }        Stack<Integer> s = new Stack<Integer>();        int i = 0;        while(i < height.length) {            if (s.isEmpty() || height[s.peek()] <= height[i]) {                s.push(i++);            } else {                int lastInd = s.pop();                // height[i] < s.peek(), cur indiates the area before i ( the peak area before i)                int cur = (s.isEmpty() ? i : (i - s.peek() -1)) * height[lastInd];                max = Math.max(max, cur);            }        }        //if not empty, then the left ones are increasing series        while(!s.isEmpty()) {            int lastInd = s.pop();            int cur = (s.isEmpty() ? i : (i - s.peek() -1)) * height[lastInd];            max = Math.max(max, cur);        }        return max;    }

0 0
原创粉丝点击