0
点赞
收藏
分享

微信扫一扫

Java 第 40 课 84.柱状图中最大的矩形 85.最大矩形



第 40 课

  • 84.柱状图中最大的矩形
  • 85.最大矩形


84.柱状图中最大的矩形

Java 第 40 课 84.柱状图中最大的矩形 85.最大矩形_List


计算每一根柱子高度构成的最大矩形面积,即作用范围 * 高度。每根柱子向左右扩展寻找它作为最小值的作用范围。

class Solution:
    def largestRectangleArea(self, heights: List[int]) -> int:      
        q, n, h = [], len(heights), heights

        # 方法一:用两个列表保存边界,即左右边界分开确定。
        # left, right = [-1] * n, [n] * n
        # for i in range(n):
        #     while q and h[q[-1]] > h[i]: # i 是栈顶的右边界
        #         right[q.pop()] = i
        #     if q: left[i] = q[-1] # 当前栈顶是 i 的左边界
        #     q.append(i)
        # # 统计每根柱子作为最小值的面积
        # ans = max((right[i] - left[i] - 1) * h[i] for i in range(n))

        # 方法二:计算当前栈顶的贡献值        
        for i, x in enumerate(h + [-1]): # 哨兵 最后无法确定右边时使用
            while q and h[q[-1]] > x:
                j = q.pop()
                # 栈空左边界取 -1,不空取栈顶、右边界是 i,计算 j 的贡献值。
                ans = max(ans, h[j] * (i - (q[-1] if q else -1) - 1))
            q.append(i)
            
        return ans

class Solution {
    public int largestRectangleArea(int[] heights) {
        int n = heights.length, ans = 0; int[] h = heights;
        Deque<Integer> q = new LinkedList<>();

        // int[] a = new int[n], b = new int[n];
        // Arrays.fill(b, n);
        // for (int i = 0; i < n; i++){
        //     while (!q.isEmpty() && h[i] < h[q.peek()])
        //         b[q.pop()] = i; // i 作为弹出元素的右边界
        //     a[i] = q.isEmpty() ? -1 : q.peek();
        //     q.push(i);
        // }
        // for (int i = 0; i < n; i++){
        //     ans = Math.max(ans, (b[i] - a[i] - 1) * h[i]);
        // }

        for (int i = 0; i <= n; i++){ // i == n 不能确定右边时使用
            while (!q.isEmpty() &&(n == i || h[i] < h[q.peek()])){
                int j = q.pop(), k = q.isEmpty() ? -1 : q.peek();
                ans = Math.max(ans, h[j] * (i - k - 1));
            }
            q.push(i);
        }
        
        return ans;
    }
}

85.最大矩形

class Solution:
  def maximalRectangle(self, matrix: List[List[str]]) -> int:       
    # 记录当前位置上方连续“1”的个数
    pre, ans = [0] * (len(matrix[0]) + 1), 0
    for row in matrix:
        for j, v in enumerate(row):
            pre[j] = (pre[j] + 1) * int(v)
        # 把 pre 看成柱子高度同 84 题
        q = [-1] # 哨兵
        for i, x in enumerate(pre):
            while pre[q[-1]] > x:
                j = q.pop()            
                ans = max(ans, pre[j] * (i - q[-1] - 1))
            q.append(i)

    return ans


举报

相关推荐

0 条评论