算法学习之动态规划(leetcode 85. Maximal Rectangle)
来源:互联网 发布:mac系统下载栏不是扇形 编辑:程序博客网 时间:2024/05/20 23:39
0x01题目
85. Maximal RectangleGiven a 2D binary matrix filled with 0's and 1's, find the largest rectangle containing only 1's and return its area.For example, given the following matrix:1 0 1 0 01 0 1 1 11 1 1 1 11 0 0 1 0Return 6.
0x02解析
使用动态规划的思想去解决这个问题,自己总结的动态规划三要素:定义概念、边界初始化、一般情况递推,两个难点是:角标索引问题、递推情况剖析。
cur_left
定义为在一个字符数组中,当前元素可以延伸到最左边元素的下标(当前元素为0,则这个值为0)。如在字符数组"0111001110"
,对第三个1
,其cur_left=1
,对最后一个0
,其cur_left=0
。其示意图如下图所示
cur_right
定义为在一个字符数组中,当前元素可以延伸到最右边元素的下标+1(当前元素为0,则这个值为字符数组的长度)。如在字符数组"0111001110"
,对第四个1
,其cur_right=8+1
,对第一个0,其cur_right=10
,其示意图如下图所示
总结:cur_left
和cur_right
均由当前行的值来确定。如果当前值为'1'
,则cur_left
和cur_right
均不变;如果当前值为'0'
,则cur_left
值为当前元素右侧,cur_right
值为当前元素位置。(左闭右开) left[i][j]
定义为在第i行第j列处,可以延伸到最左边元素的下标。 right[i][j]
定义为在第i行第j列处,可以延伸到最右边元素的下标+1。
核心思路是从第一行开始一行一行地处理,使[i, j]
处最大子矩阵的面积是(right(i, j)-left(i, j))*height(i, j)
。其中height
统计当前位置及往上'1'
的数量;left
和right
是高度是当前点的height
值的左右边界,即是以当前点为中心,以height为高度向两边扩散的左右边界。
left(i,j) = max(left(i-1,j), cur_left)right(i,j) = min(right(i-1,j), cur_right)if matrix[i][j]=='1', height(i,j) = height(i-1,j) + 1;if matrix[i][j]=='0', height(i,j) = 0;
left
、right
和height
的值均可以通过前一行和当前行的值来确定,因此,逐行遍历即可。
举例说明。字符长方形如下:
0 0 0 1 0 0 0 0 0 1 1 1 0 0 0 1 1 1 1 1 0
则left
(l
)、right
(r
)和height
(h
)的值如下所示
row 0: l: 0 0 0 3 0 0 0 r: 7 7 7 4 7 7 7 h: 0 0 0 1 0 0 0row 1: l: 0 0 2 3 2 0 0 r: 7 7 5 4 5 7 7 h: 0 0 1 2 1 0 0 row 2: l: 0 1 2 3 2 1 0 r: 7 6 5 4 5 6 7 h: 0 1 2 3 2 1 0
0x03代码
public class Solution { public int maximalRectangle(char[][] matrix) { if(matrix == null || matrix.length == 0 || matrix[0] == null) return 0; int m = matrix.length, n = matrix[0].length; int[] l = new int[n]; int[] r = new int[n]; int[] h = new int[n]; int result = 0; for(int i = 0; i < n; i++){ l[i] = 0; r[i] = n; h[i] = 0; } for(int i = 0; i < m; i++){ int cur_left = 0, cur_right = n; for(int j = 0; j < n; j++){ if(matrix[i][j] == '1') h[j] += 1; else h[j] = 0;// System.out.print(h[j]);// System.out.print(" "); } for(int j = 0; j < n; j++){ if(matrix[i][j] == '1'){ l[j] = Math.max(l[j], cur_left); } else{ l[j] = 0; cur_left = j + 1; }// System.out.print(l[j]);// System.out.print(" "); } for(int j = n-1; j >= 0; j--){ if(matrix[i][j] == '1'){ r[j] = Math.min(r[j], cur_right); } else{ r[j] = n; cur_right = j; }// System.out.print(r[j]);// System.out.print(" "); } for(int j = 0; j < n; j++){ result = Math.max(result, (r[j] - l[j]) * h[j]); } System.out.println(); } return result; }}
参考 https://discuss.leetcode.com/topic/6650/share-my-dp-solution
参考 http://blog.csdn.net/makuiyu/article/details/44857479
- 算法学习之动态规划(leetcode 85. Maximal Rectangle)
- LeetCode 85. Maximal Rectangle&221. Maximal Square--动态规划
- leetcode之Maximal Rectangle
- LeetCode之Maximal Rectangle
- LeetCode 85. Maximal Rectangle
- [Leetcode] 85. Maximal Rectangle
- LeetCode --- 85. Maximal Rectangle
- [LeetCode]*85.Maximal Rectangle
- [leetcode] 85.Maximal Rectangle
- Leetcode 85. Maximal Rectangle
- leetcode 85. Maximal Rectangle
- LeetCode 85. Maximal Rectangle
- Leetcode 85. Maximal Rectangle
- Leetcode:85. Maximal Rectangle
- LeetCode 85. Maximal Rectangle
- LeetCode-85.Maximal Rectangle
- leetcode.85. Maximal Rectangle
- leetcode 85. Maximal Rectangle
- L1-007. 念数字 Java
- c++中 打开一个文件夹下的所有特定格式的文件(如JPG)
- Javascript的this用法
- 华为代码风格要求
- eclipse-git 插件
- 算法学习之动态规划(leetcode 85. Maximal Rectangle)
- spring mvc 导出Excel
- 文件的读写
- Spring系列之Spring常用注解总结
- Ubuntu16.04将python2切换为python3
- 排序之堆排序
- 最大子数组
- 史上最全的SpringMVC学习笔记
- 腾讯代码风格要求