public int largestRectangleArea(int[] height) {
        if (height == null || height.length == 0) {
            return 0;
        } else if (height.length == 1) {
            return height[0];
        }
        // use a stack to store min-heights, collapse when new height is smaller than stack[top]
        int[] minStack = new int[height.length];
        int max = height[0], top = 0;
        minStack[0] = 0;
        for (int i = 1; i <= height.length; i ++) {
            int curHeight = i == height.length ? -1 : height[i];
            // collapse and collect max
            while (top >= 0 && height[minStack[top]] >= curHeight) {
                int width = top == 0 ? i : (i - minStack[top - 1] - 1);
                int rect = height[minStack[top]] * width;
                if (max < rect) {
                    max = rect;
                }
                top --;
            }
            // store
            minStack[++top] = i;
        }
        return max;
    }