📜  最多移除一个空细胞后,非空细胞的最长子阵列(1)

📅  最后修改于: 2023-12-03 14:55:18.009000             🧑  作者: Mango

最多移除一个空细胞后,非空细胞的最长子阵列

问题描述

给定一个由 '0''1' 组成的二维矩阵 matrix,你需要找到其中一个最大的子阵列,其中最多只能移除一个 '0' 细胞,在移除该 '0' 细胞后,剩余非空细胞能够组成一个最大的矩形。

解法思路

本题的解法比较经典,采用"柱状图"和"单调栈"的思想。

首先,用一个数组 height 记录从上到下,对于每一列连续的 "1" 的数目。然后对于每一行,都按照柱状图中的那种做法,用单调栈求出右边界和左边界。

最后,对于每一个位置,找到“以该位置为底部的最大矩形面积”,就是该位置所能贡献的最大答案。

单调栈解法经典同款题:LeetCode 84. 柱状图中最大的矩形

代码实现
class Solution:
    def maximalRectangle(self, matrix: List[List[str]]) -> int:
        if not matrix:
            return 0

        m, n = len(matrix), len(matrix[0])
        height = [0] * n
        ans = 0

        for i in range(m):
            for j in range(n):
                if matrix[i][j] == '1':
                    height[j] += 1
                else:
                    height[j] = 0

            left, right = [-1] * n, [n] * n
            stack = []

            for j in range(n):
                while stack and height[stack[-1]] >= height[j]:
                    right[stack[-1]] = j
                    stack.pop()
                left[j] = stack[-1] if stack else -1
                stack.append(j)

            for j in range(n):
                ans = max(ans, height[j] * (right[j] - left[j] - 1))

        return ans

代码说明:

  1. 先处理 height 数组。该数组记录的是下标对应的一列中最高的 "1" 的个数。
  2. 在第 $i$ 行,按照柱状图算法,用单调栈求出该位置所在的最大矩形的左右边界。
  3. 在第 2 步中,找到每个位置所能贡献的最大矩形面积,将答案不断取 $\max$。