85. 最大矩形

64 阅读1分钟

给定一个仅包含 0 和 1 、大小为 rows x cols 的二维二进制矩阵,找出只包含 1 的最大矩形,并返回其面积。

示例 1:

image.png

输入:matrix = 
[["1","0","1","0","0"],
["1","0","1","1","1"],
["1","1","1","1","1"],
["1","0","0","1","0"]]
输出:6
解释:最大矩形如上图所示。

示例 2:

输入: matrix = []
输出: 0

示例 3:

输入: matrix = [["0"]]
输出: 0

示例 4:

输入: matrix = [["1"]]
输出: 1

示例 5:

输入: matrix = [["0","0"]]
输出: 0

提示:

  • rows == matrix.length
  • cols == matrix[0].length
  • 1 <= row, cols <= 200
  • matrix[i][j] 为 '0' 或 '1'

题解:

/**
 * @param {character[][]} matrix
 * @return {number}
 */
// 方法一:暴力法 时间复杂度:O(m^2n)  空间复杂度:O(mn)
var maximalRectangle = function (matrix) {
    // 获取二进制矩阵行数
    let x = matrix.length;
    if (x == 0) return 0
    // 获取二进制矩阵列数
    let y = matrix[0].length;
    // 获取二进制矩阵 每个位置填充为0
    let newArr = new Array(x).fill(0).map(() => new Array(y).fill(0))

    for (let i = 0; i < x; i++) {
        for (let j = 0; j < y; j++) {
            if (matrix[i][j] == '1') {
                // 当前位置为1时 如果是第一列 默认为1
                // 如果后面连续为1累加处理
                newArr[i][j] = +(j == 0 ? 0 : matrix[i][j - 1]) + 1
            }
        }
    }
    // 定义面积初始值
    let ret = 0
    for (let i = 0; i < x; i++) {
        for (let j = 0; j < y; j++) {
            // 二进制矩阵位置为0跳出
            if (matrix[i][j] === '0') {
                continue;
            }
            // 获取当前位置为1的宽度,也就是当前行当前位置有几个1
            let width = newArr[i][j];
            let area = width;
            // 循环当前行,以及上面行所包含的面积
            for (let k = i - 1; k >= 0; k--) {
                // 获取当前位置最小包含宽度
                width = Math.min(width, newArr[k][j]);
                // 最小的高度  (i - k + 1)
                area = Math.max(area, (i - k + 1) * width);
            }
            // 获取最大值
            ret = Math.max(ret, area);
        }
    }
    return ret
};
// 方法二:单调栈 时间复杂度:O(mn)  空间复杂度:O(mn)
var maximalRectangle = function (matrix) {
    let x = matrix.length;
    if (x == 0) return 0;
    let y = matrix[0].length

    let res = 0;
    // 开辟空间多添一项0 避免原高度最后一直递增 无法有机会计算
    let heights = new Array(y + 1).fill(0);
    for (let row = 0; row < x; row++) {
        //每一层 高度会有变化:可能继续增1, 可能直接归零
        for (let col = 0; col < y; col++) {
            if (matrix[row][col] == '1') {
                heights[col] += 1;
            } else {
                heights[col] = 0;
            }
        }// 求出每一层的 heights[] 然后传给84题的函数  更新一下最大矩形面积
        res = Math.max(res, largestRectangleArea(heights));
    }
    return res;
};
// 84题 单调递增栈解法
let largestRectangleArea = arr => {
    let stack = [], max = 0;
    for (let [i, val] of arr.entries()) {
        // 非单调递增不可入栈 先处理
        while (stack.length && val < arr[stack.slice(-1)]) {
            let h = arr[stack.pop()];
            let w = stack.length > 0 ? i - stack.slice(-1) - 1 : i;
            max = Math.max(max, h * w); // 更新一下max
        }
        // 注意栈中存放的是下标,弹出的时候才可计算出宽度
        stack.push(i);
    }
    return max;
}

来源:力扣(LeetCode)

链接:leetcode.cn/problems/ma…

著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。