【栈】A012_LC_柱状图中最大的矩形(暴力 / 单调栈)

一、Problem

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.
【栈】A012_LC_柱状图中最大的矩形(暴力 / 单调栈)_第1张图片

Example:
Input: [2,1,5,6,2,3]
Output: 10

二、Solution

方法一:暴力(超时)

  • 对于位置 i i i,要想和位置 i i i 的柱形拼接,那么左边或右边都一定要比自己大,才能将 h[i] 用上, 所以我们搜索 i i i 位置的左右两端第一个小于 h[i] 的柱子,此时的面积就是 h [ i ] × ( r − l + 1 ) h[i] × (r-l+1) h[i]×(rl+1)
  • 为什么只找到第一个小于 h[i] 的位置呢?因为高度差至少为 1,而左移或右移一个单位虽然长度变长了 2,但如果高度小了,最好的情况就是少了 1,但不可能每次都是最好的,所以枚举到第一个小于 h[i] 的就足够了。
class Solution {
    public int largestRectangleArea(int[] h) {
    	int n = h.length, max = 0;
        if (n == 1) 
            return h[0];
    	for (int i = 0; i < n; i++) {
    		int j, k;
			for (j = i; j >= 0 && h[j] >= h[i]; j--) 
			for (k = i; k < n && h[k] >= h[i]; k++)
			max = Math.max(max, (k-j+1) * h[i]);
    	}
    	return max;
    }
}

复杂度分析

  • 时间复杂度: O ( n 2 ) O(n^2) O(n2)
  • 空间复杂度: O ( 1 ) O(1) O(1)

方法二:单调栈

在暴力法中,我们发现了一个性质:我们并不需要用 O(n) 的时间将在 i i i 两端且高度比位置 h [ i ] h[i] h[i] 要低的柱子找出来,用单调栈 O(1) 即可解决…

交了 n 发,WA 了 n 次:stack 为空则表示做/右都是比自己高的柱子,那么此时 l[i] = 0 还是 l[i] = -1,这个真不好搞…

就比如 [1, 1] 吧,如果 l[i] = 0,那么 l[0] = 0,l[1] = 0;r[0] = 2,r[1] = 2,(2 - 0 - 1) × 1 = 1,不符…

class Solution {
    public int largestRectangleArea(int[] h) {
    	int n = h.length, max = 0;
        if (n == 1)
            return h[0];
        Stack<Integer> st = new Stack<>();
        int l[] = new int[n], r[] = new int[n];
    	for (int i = 0; i < n; i++) {
    		while (!st.isEmpty() && h[st.peek()] >= h[i]) {
    			st.pop();
    		}
    		l[i] = st.isEmpty() ? -1 : st.peek(); //st为空,则表示左边都是比自己大的
    		st.push(i);
    	}
    	st.clear();
    	for (int i = n-1; i >= 0; i--) {
    		while (!st.isEmpty() && h[st.peek()] >= h[i]) {
    			st.pop();
    		}
    		r[i] = st.isEmpty() ? n : st.peek();//st为空,则表示右边都是比自己大的
    		st.push(i);
    	}
    	for (int i = 0 ; i < n; i++)
    		max = Math.max(max, (r[i] - l[i] - 1) * h[i]);
    	return max;
    }
}

复杂度分析

  • 时间复杂度: O ( n ) O(n) O(n)
  • 空间复杂度: O ( n ) O(n) O(n)

你可能感兴趣的:(#,堆)