python输出由*组成的正方形_221. 存在正方形(Python)

题目

难度:★★★★☆

类型:二维数组

方法:动态规划

在一个由 0 和 1 组成的二维矩阵内,找到只包含 1 的最大正方形,并返回其面积。

示例:

输入:

1 0 1 0 0

1 0 1 1 1

1 1 1 1 1

1 0 0 1 0

输出: 4

解答

方法1:暴力求解

如果采用暴力求解方法,可以遍历每一个位置,然后判断以该位置为左上角的最大正方形的大小,通过一层一层添加的方式寻找以该点为左上角的正方形面积极限。

class Point:

def __init__(self, loc):

self.h = loc[0]

self.w = loc[1]

self.value = loc

@property

def next_left(self):

return Point((self.h, self.w-1))

@property

def next_right(self):

return Point((self.h, self.w+1))

@property

def next_top(self):

return Point((self.h-1, self.w))

@property

def next_down(self):

return Point((self.h+1, self.w))

def get_half_circle(self, layer=1):

"""

获取右下角方向的所有相邻元素,第layer层

:return:

"""

start_point = Point((self.h, self.w+layer))

res = [start_point]

# 竖着的一列

for r in range(self.h+1, self.h+layer+1, 1):

res.append(Point((r, self.w+layer)))

# 横着的一列

for c in range(self.w+layer-1, self.w-1, -1):

res.append((Point((self.h+layer, c))))

return res

class Board:

def __init__(self, value):

assert value is not None and value[0] is not None, 'Not a board.'

self.value = value

self.height = len(value)

self.width = len(value[0])

def get_value(self, point):

if self.is_valid_point(point):

return self.value[point.h][point.w]

def set_value(self, point, value):

if self.is_valid_point(point):

self.value[point.h][point.w] = value

def is_valid_point(self, point):

return 0 <= point.h < self.height and 0 <= point.w < self.width

def find_square(self, point, value='1'):

"""

获得以point为左上角的最大正方形的边长

:param point:

:param value:

:return:

"""

assert isinstance(point, Point)

max_edge = 0

while True:

for test_point in point.get_half_circle(max_edge):

if self.get_value(test_point) != value:

return max_edge

max_edge += 1

class Solution:

def maximalSquare(self, matrix):

if not matrix or not matrix[0]:

return 0

board = Board(matrix)

res = 0

for h in range(board.height):

for w in range(board.width):

cur_edge = board.find_square(Point((h, w)), '1')

res = max(res, cur_edge)

return res ** 2

方法2:动态规划

可以使用动态规划解决这个问题,设输入matrix的高和宽分别为height和width,定义一个同样维度的dp矩阵,该矩阵中的某一点p(h,w)处的值dp[h][w]表示以p点为右下角的最大正方形的边长。

定义初始条件,对于第一行和第一列,dp矩阵中的数值取决于该点处的值是否为1,如果是设置为1,否则设置为0.

递推关系式。这个比较重要,点(h,w)处dp的值的计算需要(h-1,w),(h,w-1)和(h-1,w-1)三个点在dp处的值一起计算,公式为:

dp[h][w] = min(dp[h-1][w], dp[h][w-1], dp[h-1][w-1]) + 1

因为当前点能否组成正方形是由左上角三个点的能组成的最小的正方形决定的。

最后定义一个变量,用于存储计算过程中出现的最大正方形的边长。

一个例子,

matrix = [["1","0","1","0","0"],

["1","0","1","1","1"],

["1","1","1","1","1"],

["1","0","0","1","0"]]

得到的dp矩阵为:

[[1, 0, 1, 0, 0],

[1, 0, 1, 1, 1],

[1, 1, 1, 2, 2],

[1, 0, 0, 1, 0]]

class Solution:

def maximalSquare(self, matrix):

if not matrix or not matrix[0]:

return 0

height, width = len(matrix), len(matrix[0])

dp = [[0 for _ in range(width)] for _ in range(height)]

max_edge = 0

for h in range(height):

for w in range(width):

if matrix[h][w] == '1':

if h == 0 or w == 0:

dp[h][w] = 1

else:

dp[h][w] = min(dp[h-1][w], dp[h][w-1], dp[h-1][w-1]) + 1

else:

dp[h][w] = 0

max_edge = max(max_edge, dp[h][w])

return max_edge ** 2

如有疑问或建议,欢迎评论区留言~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值