问题是在矩阵中找到最大的+(加号):
“给定一个只包含字符'0'和'1'的矩阵,找到由1组成的最大加号(+)并返回其等级。在这种情况下,Rank表示加号边缘的长度为了成为有效的加号,边缘的长度必须相等。“
我目前的算法如下。基本上它通过大小为n的矩阵,三次。首先,它通过它并确定其左侧/上方1s的值。第二遍确定向右/向下1s的值。第三个比较生成的4个矩阵并找到最小值。这些值的最大值就是答案。
我想知道如何优化算法。矩阵的长度可以达到1000x1000。有没有办法通过一次矩阵来确定答案?如果是这样,怎么办呢。或者是否有更好的方法来确定与此完全不同的答案?
def biggestPlus(matrix):
def get_left_up():
dp_left = [[-1 for _ in row] for row in matrix]
dp_up = [[ -1 for _ in row ] for row in matrix ]
for y, row in enumerate(matrix):
for x, val in enumerate(row):
if val == '1':
#####FOR DP_LEFT
if x != 0:
dp_left[y][x] = dp_left[y][x-1] + 1
else:
dp_left[y][x] = 0
#####FOR DP_UP
if y != 0:
dp_up[y][x] = dp_up[y-1][x] + 1
else:
dp_up[y][x] = 0
return dp_left, dp_up
def get_right_down():
dp_right = [[-1 for _ in row] for row in matrix]
dp_down = [[-1 for _ in row] for row in matrix]
for y in range(len(matrix)-1,-1,-1):
row = matrix[y]
for x in range(len(row) - 1, -1, -1):
val = matrix[y][x]
if val == '1':
#####FOR DP_RIGHT
if x < len(row)-1:
dp_right[y][x] = dp_right[y][x + 1] + 1
else:
dp_right[y][x] = 0
#####FOR DP_DOWN
if y < len(matrix)-1:
dp_down[y][x] = dp_down[y + 1][x] + 1
else:
dp_down[y][x] = 0
return dp_right, dp_down
def getBiggestPlus(dp_left,dp_up,dp_right,dp_down):
#####GET MIN OF 4 MATRICES
result = 0
for y, row in enumerate(dp_left):
for x, val in enumerate(row):
minimum = min(dp_left[y][x],dp_down[y][x],dp_right[y][x],dp_up[y][x])
result = max(result,minimum) #####ANSWER IS THE MAX
return result
dp_left, dp_up = get_left_up()
dp_right, dp_down = get_right_down()
return getBiggestPlus(dp_left,dp_up,dp_right,dp_down)
示例输入:
matrix = ["0110010",
"1010101",
"1111111",
"0010000",
"0000000"]
print("Answer:", biggestPlus(matrix))
答案 0 :(得分:0)
在N行的方阵中,边长 n 的+
必须具有长度 2n + 1 的水平部分,并且该部分无法从 n 行上方或 N - n 行下方开始,否则垂直边缘将不适合。
这个最大的+
只能放在矩阵的正中心。
我会开始扫描水平线的矩阵,并为它们寻找匹配的垂直线。考虑到剩余的垂直空间,我有一个变量 k 用于我仍然可以找到的最大加边。我从中间开始, k = N / 2 。
在每一步中,我都会寻找1
s的横向延伸长度不超过 2k + 1 ;可以有几行。对于他们每个人,我会寻找一个匹配的垂直,扫描中心的列。
寻找最大值的常见想法适用;保持最知名的结果,如果发现更好的结果,请更换。如果 k 变得小于最佳已知结果,则停止是有意义的,并忽略任何小于它的水平延伸。
获得最佳性能的技巧是并行地执行两次扫描,一次向上扫描,一次向下扫描。它们也可以按顺序运行,但是算法可能需要进行完全向上扫描,例如,什么都没有,然后在中间附近找到一个大的加号。通过锁步执行,最快的发现是最快的。
编码取决于你,但我写的第一个函数是:
def find_horizontal_stretches(matrix, line, no_shorter_than=1):
"""Returns a list of stretches as [(start, length),..],
each no shorter than indicated.
"""
def has_vertical_stretch(matrix, line, column, size):
"""Returns True iff a column of 1s of given size is present
at given column, and is centered at given line."""