// 第二想到固定某柱子, 背向雙指針, 找左右邊界(找比自己高的), 求面積classSolution {publicintlargestRectangleArea(int[] heights) {int max =0;int n =heights.length;for (int i =0; i < n ; i++) {int curr = heights[i];int left = i-1;int right = i+1;while (left >=0&& heights[left] >= curr) { left--; }while (right < n && heights[right] >= curr) { right++; } max =Math.max(max, curr*(right - left -1)); }return max; }}
mono stack
h = heights[stack.pop()]; => 7
2 - 0 - 1
i - stack.peek() - 1
area = 7 * (2 - 0 - 1)
while (!stack.isEmpty() && heights[stack.peek()] >= cur) { // find right boundint h = heights[stack.pop()]; // one by one pop to use height to cal the areaint w =stack.isEmpty() ? i : i -stack.peek() -1; // 2 - 0 - 1 ans =Math.max(ans, h * w);}
O(n), O(n)
classSolution {publicintlargestRectangleArea(int[] heights) {if (heights ==null||heights.length==0) {return0; }Stack<Integer> stack =newStack<Integer>();int ans =0;for (int i =0; i <=heights.length; i++) {int cur = (i ==heights.length) ?-1: heights[i];while (!stack.isEmpty() && heights[stack.peek()] >= cur) { // find right boundint h = heights[stack.pop()]; // one by one pop to use height to cal the areaint w =stack.isEmpty() ? i : i -stack.peek() -1; // 2 - 0 - 1 ans =Math.max(ans, h * w); } stack.push(i); }return ans; }}
readable version
i = heights.lenght , cur 設定成 -1, 用意在讓stack剩下的 pop()完(退棧)
heights[stack.peek()] >= cur => 一定 >= -1,
stack 空的時候, leftBound = -1, or stack.peek()
這樣才能算到比較低的那根到左邊界所有的面積
int rightBound = i;
int leftBound = stack.isEmpty() ? -1 : stack.peek();
2. 2
1
2會先退掉 (1比較小
2
1
到底才開始退(右邊界-1了
2退掉
1退掉, 此時stack 空了, 代表可以算左邊界 -1了
classSolution {publicintlargestRectangleArea(int[] heights) {if (heights ==null||heights.length==0) {return0; }Stack<Integer> stack =newStack<>();// stack to record index,// for i = 0 ~ heights.length// while cur >= peek(), means find right bound = i, // so pop h, get w, // if stack is empty, means left bound is -1, or left bound is stack.peek()// cal area// pushint max =0;for (int i =0; i <=heights.length; i++) {int cur = (i ==heights.length) ?-1: heights[i];while (!stack.isEmpty() && heights[stack.peek()] >= cur) {int h = heights[stack.pop()];int rightBound = i;int leftBound =stack.isEmpty() ?-1:stack.peek(); max =Math.max(max, h*(rightBound - leftBound -1)); }stack.push(i); }return max; }}
newest version
classSolution {publicintlargestRectangleArea(int[] heights) {Deque<Integer> stack =newArrayDeque<>();int max =Integer.MIN_VALUE;// 因為是要左邊界右邊界, 所以要執行到 height的尾巴 i <= heights.lengthfor (int i =0; i <=heights.length; i++) { // why <= heights.lengthint curr = (i ==heights.length) ?-1: heights[i];while (!stack.isEmpty() && curr <= heights[stack.peek()]) {int h = heights[stack.pop()];int rightBound = i;int leftBound =stack.isEmpty() ?-1:stack.peek(); max =Math.max(max, h*(rightBound - leftBound -1)); }stack.push(i); }return max; }}