📅  最后修改于: 2023-12-03 15:36:42.411000             🧑  作者: Mango
给定一个非空n*m的矩阵matrix,使矩阵回文所需的最小增量是指将矩阵中非对称元素的值调整到相等的最小操作次数。
例如,对于矩阵:
1 2 3
4 5 6
7 8 9
我们需要将左下角的4、7改为2来构造回文矩阵,则最小增量为2。
现在,你需要编写一个程序,实现计算使给定矩阵回文所需的最小增量的功能,并返回答案。
整个算法分为三个部分,分别是:确定转化后的矩阵大小、构造"回文"矩阵、计算最小增量。
首先,我们需要对原始矩阵进行转化,以便更好地进行回文构造和计算最小增量。具体地,我们将原始矩阵拆分成两个大小相等的部分,每一部分包含连续的m/2列。如下图所示,原始矩阵matrix被转化为两个子矩阵left_matrix和right_matrix。
注意,当m为奇数时,由于中间一列将会被拆分到左边子矩阵中,因此每一个右边子矩阵中的元素与每一个左边子矩阵中的元素一一对应。因此,左边子矩阵和右边子矩阵的大小均为n*m/2。
接下来,我们需要构造一个"回文"矩阵。具体地,我们将左边子矩阵中的每一个元素与其在右边子矩阵中的对称元素进行比较,如果它们不相等,则将左边子矩阵中的元素更新为右边子矩阵中的对称元素中的较小值。
显然,我们只需要遍历左边子矩阵中的所有元素,计算它们与对称元素的比较结果即可。
最后,我们需要计算最小增量。这个部分的思路比较简单,我们只需要遍历左边子矩阵中的每一个元素,统计需要将它们更新为对称元素所需的操作次数即可。
对于每一个左边子矩阵中的元素,假设其位于(j,k)位置,则其对称元素位于(j,m-k-1)位置。假设其值分别为left_matrix[j][k]和right_matrix[j][m-k-1],则它们的差值为delta = right_matrix[j][m-k-1] - left_matrix[j][k]。显然,我们需要将left_matrix[j][k]的值提升为right_matrix[j][m-k-1]的值,因此需要进行left_matrix[j][k] += delta的操作。
需要注意的是,如果delta的值为负数,说明left_matrix[j][k]的值已经比right_matrix[j][m-k-1]的值更大了,此时我们不需要进行操作,因为left_matrix[j][k]的值已经是对称元素的值了。因此我们需要使用max函数快速判断需要不需要进行更新操作。
def palindrome_matrix(matrix: List[List[int]]) -> int:
n, m = len(matrix), len(matrix[0])
left_matrix = [row[:m//2] for row in matrix]
right_matrix = [row[m//2:][::-1] for row in matrix]
# 构造回文矩阵
for i in range(n):
for j in range(m//2):
if left_matrix[i][j] != right_matrix[i][j]:
left_matrix[i][j] = right_matrix[i][j] = min(left_matrix[i][j], right_matrix[i][j])
# 计算最小增量
ans = 0
for i in range(n):
for j in range(m//2):
delta = right_matrix[i][m-j-1] - left_matrix[i][j]
if delta > 0:
ans += delta
left_matrix[i][j] += delta
right_matrix[i][m-j-1] -= delta
else:
ans -= delta
return ans