博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[LeetCode]Maximal Rectangle
阅读量:6258 次
发布时间:2019-06-22

本文共 2725 字,大约阅读时间需要 9 分钟。

Maximal Rectangle

Given a 2D binary matrix filled with 0's and 1's, find the largest rectangle containing all ones and return its area.

分析

这道题是要在所有里面全为‘1’的长方形里找出最大面积那个。往往这种找最大的题目可以考虑用DP,算出所有全‘1'的长方形的面积,然后过程中不断更新最大面积。但是这道题难点是对于一个点来说DP表示什么,以及跟周边点DP是什么关系。

我们可以这样考虑,对于一个里面全部为’1‘的长方形来说,算其面积,最重要的几个特征是什么?有三个变量必须知道:

1. 高度h2. 左边界的x值x13. 右边界的x值x2这样面积即为h * (x2 - x1)

所以对于矩阵中任意一点,我们可以根据以上三个变量维护三个数组,分别为height[][], right[][], left[][],来表示以这个点为底边的任意一点,以这个点为最底向上连续’1‘的长度为轴向左向右扫,能够组成的面积最大的内部全部为’1‘的长方形。height[i][j]表示以(i, j)为底的往上最大连续’1‘的高度。left[i][j], right[i][j]表示以(i, j)点及其height[i][j]高度组成的中轴向左扩散的左边界的横坐标与向右扩散的右边界的横坐标 + 1, 扩散的要求是必须全部为’1‘。我们可以得出以下推导公式:

height[i][j] = matrix[i][j] == '1' ? height[i - 1][j]++ : 0;left[i][j] = Math.max(left[i - 1][j], currLeft),currLeft表示对ith行而言,从(i,j)向左连续为'1'直至(i, currLeft)那个点;right[i][j] = Math.min(right[i - 1][j], currRight), currRight表示ith行而言,从(i,j)向右连续为'1'直至(i, currRight - 1)那个点;;

为便于理解,见下例:

matrix:0 0 0 1 0 0 0 0 0 1 1 1 0 0 0 1 1 1 1 1 0各点height, left及right值如下:row 0:h: 0 0 0 1 0 0 0l: 0 0 0 3 0 0 0r: 7 7 7 4 7 7 7row 1:h: 0 0 1 2 1 0 0l: 0 0 2 3 2 0 0r: 7 7 5 4 5 7 7 row 2:h: 0 1 2 3 3 1 0l: 0 1 2 3 2 1 0r: 7 6 5 4 5 6 7

注意代码实现过程中当本身值为'0'时,我们可以设置成left[i][j] = 0, right[i][j] = n, 并非实际意义,只是为了下一排计算使用。虽然不是实际意义,也不影响后面面积的计算,因为height[i][j] == 0, 面积必然为0,左右边界值不影响面积计算。

当然代码实现过程中,由于每个点只是与上一行有关,可以用一维数组代替二维数组。

复杂度

time: O(mn), space: O(n)

代码

public class Solution {    public int maximalRectangle(char[][] matrix) {        int m = matrix.length;        if (m == 0)            return 0;        int n = matrix[0].length;                int[] height = new int[n];        int[] left = new int[n];        int[] right = new int[n];        Arrays.fill(right, n); // 初始右边界为最右                int max = 0;              for (int i = 0; i < m; i++) {            int currLeft = 0;            int currRight = n;                        // 从左到右算height及left            for (int j = 0; j < n; j++) {                if (matrix[i][j] == '1') {                    height[j]++;                    left[j] = Math.max(left[j], currLeft);                } else {                    height[j] = 0;                    left[j] = 0;                     currLeft = j + 1;                }            }                        // 从右到左算right            for (int j = n - 1; j >= 0; j--) {                if (matrix[i][j] == '1') {                    right[j] =  Math.min(right[j], currRight);                } else {                    right[j] = n;                     currRight = j;                }            }                                   for (int j = 0; j < n; j++) {                int area = (right[j] - left[j]) * height[j];                max = Math.max(max, area);            }        }                return max;    }}

转载地址:http://dthsa.baihongyu.com/

你可能感兴趣的文章
简单的ajax封装
查看>>
PHP初学者必须掌握的10个知识点
查看>>
[Asp.Net]获取客户端ip和mac地址
查看>>
Arcengine设置坐标系(转载)
查看>>
php字符串操作集锦
查看>>
【WPF】C#代码动态改变控件的样式
查看>>
P1115 最大子段和
查看>>
【翻译自mos文章】检查$ORACLE_HOME是否是RAC的HOME的方法以及relink RAC的Oracle binary的方法...
查看>>
PHP函数篇详解十进制、二进制、八进制和十六进制转换函数说明
查看>>
php max_execution_time执行时间问题
查看>>
Hystrix系列-5-Hystrix的资源隔离策略
查看>>
005-ant design -结合echart
查看>>
TCP交互数据流 成块数据流
查看>>
位置+推荐
查看>>
PEP python enhanced prposals
查看>>
retools 0.1 : Python Package Index
查看>>
python模块——logging 这篇讲得比较能懂
查看>>
【017】◀▶ C#学习(九) - ADO.NET
查看>>
English
查看>>
解剖SQLSERVER 第二篇 对数据页面头进行逆向(译)
查看>>