84. 柱状图中最大的矩形(单调栈)

165 阅读1分钟

  • 解法一:暴力法,以当前点为高度,分别往左右寻找不低于当前高度的矩形。
public class Num84柱状图中最大的矩形 {
    public int largestRectangleArea(int[] heights) {
        int n = heights.length, ans = 0;
        if (heights.length == 0) return ans;
        for (int i = 0; i < n; i++) {
            int curHeight = heights[i], left = i - 1, right = i + 1;
            while (left >= 0 && heights[left] >= curHeight) left--;
            while (right < n && heights[right] >= curHeight) right++;
            ans = Math.max(ans, curHeight * (right - left - 1));
        }
        return ans;
    }
}
  • 解法二:单调栈。
 public static int largestRectangleArea3(int[] heights) {
        int n = heights.length;
        int[] left = new int[n];
        int[] right = new int[n];
        Stack<Integer> stack = new Stack<>();
        for (int i = 0; i < n; i++) {
            while (!stack.isEmpty() && heights[stack.peek()] >= heights[i]) stack.pop();
            if (stack.isEmpty()) left[i] = -1;
            else left[i] = stack.peek();
            stack.push(i);
        }
        while (!stack.isEmpty()) stack.pop();
        for (int i = n - 1; i >= 0; i--) {
            while (!stack.isEmpty() && heights[stack.peek()] >= heights[i]) stack.pop();
            if (stack.isEmpty()) right[i] = n;
            else right[i] = stack.peek();
            stack.push(i);
        }
        int ans = 0;
        for (int i = 0; i < n; i++) {
            ans = Math.max(ans, heights[i] * (right[i] - left[i] - 1));
        }
        return ans;
    }
  • 解法三:单调栈改进。

//list转arr,arr转list

public int largestRectangleArea2(int[] heights) {
        //int数组转list
        List<Integer> list = Arrays.stream(heights).boxed().collect(Collectors.toList());
        list.add(-1);
        Stack<Integer> stack = new Stack<>();
        int ans = 0;
        for (int i = 0; i < list.size(); i++) {
            while (!stack.isEmpty() && list.get(i) < list.get(stack.peek())) {
                int h = list.get(stack.pop());
                if (stack.isEmpty()) ans = Math.max(ans, i * h);
                else ans = Math.max(ans, h * (i - stack.peek() - 1));
            }
            stack.push(i);
        }
        return ans;
    }
 //方法二:java8及以上版本
        List<Integer> list1 = Arrays.stream(array).boxed().collect(Collectors.toList());
 
        /*list转int[]*/
        //方法一:
        Integer[] intArr =  list.toArray(new Integer[list.size()]);
        //方法二:java8及以上版本
        int[] intArr1 =  list.stream().mapToInt(Integer::valueOf).toArray();