最大正方形
2016-06-21 16:07
176 查看
题目描述:在一个二维01矩阵中找到全为1的最大正方形
样例:
1 0 1 0 0
1 0 1 1 1
1 1 1 1 1
1 0 0 1 0
返回 4
求的是正方形的面积,当然,如果能知道这个正方形的边长就解决了。还是动态规划,用一个二维表格record记录运算结果,其中,record[i][j]表示源矩阵当中以第 i 行,第 j 列的元素为正方形右下角的最大正方形的边长。拿样例来说,record[2][3] = 2,而record[3][4] = 0,因为源矩阵这个位置是0. 那么什么时候record记录的值的大小会增加呢?
假设现在record[i - 1][j - 1]记录了以源矩阵中第 i - 1 行,第 j - 1 列的元素为正方形右下角的最大正方形的边长,那么record[i][j]的值就和matrix[i][j]所在的行和列有关系了。显然,沿着行(或列)的方向向左(或向上)追溯,看matrix中的元素的值是否都为1就成为这个最大正方形的边长是否能增加的唯一原因。但是这件事情单独做一遍效率实在太低,也没那个必要,既然record的每个元素记录的都是以这个元素为右下角的最大正方形边长,我们就可以通过这个边长来判断matrix[i][j]所在的行和列的,往上或往左回溯的,元素为"1"的个数。
写出状态转移方程:record[i][j] = min(record[i - 1][j], record[i][j - 1], record[i - 1][j - 1]) + 1
代码如下:
class Solution:
#param matrix: a matrix of 0 and 1
#return: an integer
def maxSquare(self, matrix):
m = len(matrix)
if m == 0:
return 0
n = len(matrix[0])
record = [[0 for j in range(n)] for i in range(m)]
# 对于第1行,第1列,当然元素是1的,以它为右下角的正方形边长就是1
for j in range(n):
if matrix[0][j] == 1:
record[0][j] = 1
for i in range(m):
if matrix[i][0] == 1:
record[i][0] = 1
i = 1
result = 0
while i < m:
j = 1
while j < n:
# 这个值是1,才有分析的必要,否则肯定是0
if matrix[i][j] == 1:
record[i][j] = min(record[i - 1][j - 1], record[i - 1][j], record[i][j - 1]) + 1
j += 1
result = max(result, max(record[i]))
i += 1
# result计算的是边长,而需要返回的是面积
return pow(result, 2)
# write your code here
样例:
1 0 1 0 0
1 0 1 1 1
1 1 1 1 1
1 0 0 1 0
返回 4
求的是正方形的面积,当然,如果能知道这个正方形的边长就解决了。还是动态规划,用一个二维表格record记录运算结果,其中,record[i][j]表示源矩阵当中以第 i 行,第 j 列的元素为正方形右下角的最大正方形的边长。拿样例来说,record[2][3] = 2,而record[3][4] = 0,因为源矩阵这个位置是0. 那么什么时候record记录的值的大小会增加呢?
假设现在record[i - 1][j - 1]记录了以源矩阵中第 i - 1 行,第 j - 1 列的元素为正方形右下角的最大正方形的边长,那么record[i][j]的值就和matrix[i][j]所在的行和列有关系了。显然,沿着行(或列)的方向向左(或向上)追溯,看matrix中的元素的值是否都为1就成为这个最大正方形的边长是否能增加的唯一原因。但是这件事情单独做一遍效率实在太低,也没那个必要,既然record的每个元素记录的都是以这个元素为右下角的最大正方形边长,我们就可以通过这个边长来判断matrix[i][j]所在的行和列的,往上或往左回溯的,元素为"1"的个数。
写出状态转移方程:record[i][j] = min(record[i - 1][j], record[i][j - 1], record[i - 1][j - 1]) + 1
代码如下:
class Solution:
#param matrix: a matrix of 0 and 1
#return: an integer
def maxSquare(self, matrix):
m = len(matrix)
if m == 0:
return 0
n = len(matrix[0])
record = [[0 for j in range(n)] for i in range(m)]
# 对于第1行,第1列,当然元素是1的,以它为右下角的正方形边长就是1
for j in range(n):
if matrix[0][j] == 1:
record[0][j] = 1
for i in range(m):
if matrix[i][0] == 1:
record[i][0] = 1
i = 1
result = 0
while i < m:
j = 1
while j < n:
# 这个值是1,才有分析的必要,否则肯定是0
if matrix[i][j] == 1:
record[i][j] = min(record[i - 1][j - 1], record[i - 1][j], record[i][j - 1]) + 1
j += 1
result = max(result, max(record[i]))
i += 1
# result计算的是边长,而需要返回的是面积
return pow(result, 2)
# write your code here
相关文章推荐
- C++动态规划之最长公子序列实例
- C++动态规划之背包问题解决方法
- C#使用动态规划解决0-1背包问题实例分析
- 动态规划
- C++ 动态规划
- 动态规划解决背包问题的核心思路
- DP(动态规划) 解游轮费用问题
- 动态规划的用法——01背包问题
- 动态规划的用法——01背包问题
- 《收集苹果》 动态规划入门
- 《DNA比对》蓝桥杯复赛试题
- 《背包问题》 动态规划
- 自顶向下动态规划解决最长公共子序列(LCS)问题
- 01背包问题
- 初学ACM - 半数集(Half Set)问题 NOJ 1010 / FOJ 1207
- 关于爬楼梯的动态规划算法
- 动态规划 --- hdu 1003 **
- DP问题各种模型的状态转移方程
- 0-1背包解题过程
- 背包问题