標籤:
題目資訊如下:
1、題目地址為:https://leetcode.com/problems/largest-rectangle-in-histogram/
2、題目意思為:
給定一個非負數組height,代表了矩形的高度(其中矩形寬度為1),求在其中能找出最大的矩形面積。
3、給的例子為: height = [2,1,5,6,2,3]. 輸出為:10.如下
那麼下面為本文,講講演算法的依據(以上面的例子為例):
1、第一個2就沒什麼講的了,面積必然為2。
2、當指標指向height[1]的時候,面積有1(也就是自身)和2(如)兩種可能。
3、當指標指向height[2]的時候,如所示,有3種面積可能。
4、當指標指向height[3]的時候,如,有4中可能(圖中少畫了h[1]-[3]的組合)
對比3、4我發現一個有用的規律:
h[2]的所有面積情況下,都可以加上h[3]所對應的面積。
也就是,如果指標所在的高度(如h[2]=5)的後面有和自己更高的或者相等的高度(如h[3]=6),那麼最大的面積就不可能是指標所在的高度和前面的組合。
用下面的圖片描述上面的規律,更加貼切。如果要在中找最大的面積,必然有高度為6的參與。
另起一段:
遇到上面這樣的排列,我們會怎麼組合?
看了上面的介紹,你肯定會說,直接1 5 6組合中找最大的,接下來再5 6 2中找最大的面積,最後再看1*4的面積。
好像有點問題,比如1 5 6 組合中,可能存在1 1 1這樣的矩陣,那麼為什麼不直接講矩陣拉到2上,也就是說1 1 1 1 = 4的面積哇?
所以總結下我們可以得到這樣的組合方法:
指標從1開始向後移動,不停的記錄資訊,直到指標指向2,由於2<6,此時開始計算前面的高度5、6的面積組合,為啥不計算1呢,由於1<2,如果最大面積組合中包含1,那麼必然包含2,如的紅框。最後我們知道,1後面高度都是大於2,那麼 面積=(2的下標-1的下標-1)*2的高度。
最後附上代碼:
public int largestRectangleArea(int[] height) { if(height == null || height.length == 0) return 0; int len = height.length; Stack<Integer> stack = new Stack<Integer>(); int max = 0; for(int i=0; i<len; i++){ if(stack.empty() || height[i] >= height[stack.peek()]){//將大於等於棧頂的height入棧,那麼中是一個不減序列 stack.push(i); } else{//height 小於棧頂的高度 int left = 0; while(!stack.empty() && height[i] < height[stack.peek()]){//直到棧頂的高度小於當前高度 left = stack.pop(); int cur = height[left] * (stack.empty()?i:i-stack.peek()-1);//入棧是遞增,出棧是遞減,也就是當前序列高度*出棧了的個數,就是當前的面積 if(max < cur){ max = cur; } } stack.push(i); } } int left = 0; while(!stack.empty()){//這裡用來處理比如[1 2 3 4 5 6 7 8]這樣的遞增序列或遞增子序列 left = stack.pop(); int cur = height[left] * (stack.empty()?len:len-stack.peek()-1); if(max < cur) max = cur; } return max; }
著作權聲明:本文為博主原創文章,未經博主允許不得轉載。
【leetcode】Largest Rectangle in Histogram