本题解的主要思路是使用动态规划来计算矩阵中任意菱形的和。首先,构建两个辅助矩阵sum1和sum2来存储从左上到右下和从右上到左下的前缀和。这样可以快速计算出任意大小的菱形和。对于每个可能的菱形中心点,遍历可能的菱形大小,利用前缀和矩阵来计算出这个菱形的总和。使用一个自定义类Answer来维护三个最大的不同的菱形和。这个类有一个方法put来更新这三个最大值,如果新的菱形和比已有的大且不重复,则更新对应的值。最后,使用get方法返回结果。这种方法可以有效地避免重复计算任意菱形的元素和,提高效率。
时间复杂度: O(m*n*min(m,n)^2)
空间复杂度: O(m*n)
# 解题类定义
class Answer:
def __init__(self):
self.ans = [0, 0, 0] # 初始化三个最大菱形和为0
def put(self, x: int):
# 更新三个最大的不同菱形和
if x > self.ans[0]:
self.ans[0], self.ans[1], self.ans[2] = x, self.ans[0], self.ans[1]
elif x != self.ans[0] and x > self.ans[1]:
self.ans[1], self.ans[2] = x, self.ans[1]
elif x != self.ans[0] and x != self.ans[1] and x > self.ans[2]:
self.ans[2] = x
def get(self) -> List[int]:
return [num for num in self.ans if num != 0] # 返回非零的最大三个和
# 主解题类
class Solution:
def getBiggestThree(self, grid: List[List[int]]) -> List[int]:
m, n = len(grid), len(grid[0]) # 获取矩阵的行数和列数
sum1 = [[0] * (n + 2) for _ in range(m + 1)] # 前缀和数组1
sum2 = [[0] * (n + 2) for _ in range(m + 1)] # 前缀和数组2
# 构建前缀和矩阵
for i in range(1, m + 1):
for j in range(1, n + 1):
sum1[i][j] = sum1[i - 1][j - 1] + grid[i - 1][j - 1]
sum2[i][j] = sum2[i - 1][j + 1] + grid[i - 1][j - 1]
ans = Answer() # 初始化Answer类
for i in range(m):
for j in range(n):
ans.put(grid[i][j]) # 单个点也视为一个菱形
for k in range(i + 2, m, 2): # 遍历所有可能的菱形大小
ux, uy = i, j
dx, dy = k, j
lx, ly = (i + k) // 2, j - (k - i) // 2
rx, ry = (i + k) // 2, j + (k - i) // 2
if ly < 0 or ry >= n:
break # 超出边界则停止
diamond_sum = (
sum2[lx + 1][ly + 1] - sum2[ux][uy + 2] +
sum1[rx + 1][ry + 1] - sum1[ux][uy] +
sum1[dx + 1][dy + 1] - sum1[lx][ly] +
sum2[dx + 1][dy + 1] - sum2[rx][ry + 2] -
(grid[ux][uy] + grid[dx][dy] + grid[lx][ly] + grid[rx][ry])
) # 计算菱形和
ans.put(diamond_sum)
return ans.get() # 返回最大的三个不同的菱形和