84. Largest Rectangle in Histogram

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.

Above is a histogram where width of each bar is 1, given height = [2,1,5,6,2,3].

The largest rectangle is shown in the shaded area, which has area = 10 unit.

For example,

Given heights = [2,1,5,6,2,3],

return 10.

 O(n^2)的答案… LTE,优化后的方案是经典的栈的思路,注意几个点:

  1. 更优秀的遍历的思路,想办法构造一个递增条件
  2. 使用栈来维持这个性质
  3. 对于不满足条件的情况,考虑状态切换以及输出值
class Solution {
    public int largestRectangleArea(int[] heights) {
        
        int ret = 0;
        //维护一个递增序列的栈,在不满足条件的时候弹出
        Stack stack = new Stack<>();
        
        if(heights.length == 0)return ret;
        
        //边界条件
        stack.push(0);
        
        for(int i= 1; i

 一个更加精简的版本…虽然没有什么区别

public int largestRectangleArea(int[] h) {
  int n = h.length, i = 0, max = 0;
    
  Stack s = new Stack<>();
    
  while (i < n) {
    // as long as the current bar is shorter than the last one in the stack
    // we keep popping out the stack and calculate the area based on
    // the popped bar
    while (!s.isEmpty() && h[i] < h[s.peek()]) {
      // tricky part is how to handle the index of the left bound
      max = Math.max(max, h[s.pop()] * (i - (s.isEmpty() ? 0 : s.peek() + 1)));
    }
    // put current bar's index to the stack
    s.push(i++);
  }
    
  // finally pop out any bar left in the stack and calculate the area based on it
  while (!s.isEmpty()) {
    max = Math.max(max, h[s.pop()] * (n - (s.isEmpty() ? 0 : s.peek() + 1)));
  }
    
  return max;
}

 这个思路…虽然在leetcode上测试效果更好,但是其实你分析一下就知道…O(n^2)

public class Solution {
public static int largestRectangleArea(int[] height) {
    if (height == null || height.length == 0) {
        return 0;
    }
    int[] lessFromLeft = new int[height.length]; // idx of the first bar the left that is lower than current
    int[] lessFromRight = new int[height.length]; // idx of the first bar the right that is lower than current
    lessFromRight[height.length - 1] = height.length;
    lessFromLeft[0] = -1;

    for (int i = 1; i < height.length; i++) {
        int p = i - 1;

        while (p >= 0 && height[p] >= height[i]) {
            p = lessFromLeft[p];
        }
        lessFromLeft[i] = p;
    }

    for (int i = height.length - 2; i >= 0; i--) {
        int p = i + 1;

        while (p < height.length && height[p] >= height[i]) {
            p = lessFromRight[p];
        }
        lessFromRight[i] = p;
    }

    int maxArea = 0;
    for (int i = 0; i < height.length; i++) {
        maxArea = Math.max(maxArea, height[i] * (lessFromRight[i] - lessFromLeft[i] - 1));
    }

    return maxArea;
}
}

 递归的思路…分析一下时间复杂度…其实是O(n^2)

Find the minimum height column with index min. The max area should exist among three possible answers:

sub-problem in index [0 ~ min]
sub-problem in index [min + 1 ~ len - 1]
height[min] * (len - 0)

public class Solution {
    public int largestRectangleArea(int[] heights) {
        if (heights == null || heights.length == 0) return 0;
        return getMax(heights, 0, heights.length);
    }    
    int getMax(int[] heights, int s, int e) {
        if (s + 1 >= e) return heights[s];
        int min = s;
        boolean sorted = true;
        for (int i = s; i < e; i++) {
            if (i > s && heights[i] < heights[i - 1]) sorted = false;
            if (heights[min] > heights[i]) min = i;
        }
        if (sorted) {
            int max = 0;
            for (int i = s; i < e; i++) {
                max = Math.max(max, heights[i] * (e - i));
            }
            return max;
        }
        int left = (min > s) ? getMax(heights, s, min) : 0;
        int right = (min < e - 1) ? getMax(heights, min + 1, e) : 0;
        return Math.max(Math.max(left, right), (e - s) * heights[min]);
    }
}

你可能感兴趣的:(数据结构与算法,leetcode,算法,数据结构与算法)