执行结果:通过
执行用时和内存消耗如下:
题目:最少翻转次数使二进制矩阵回文①
给你一个 m x n
的二进制矩阵 grid
。如果矩阵中一行或者一列从前往后与从后往前读是一样的,那么我们称这一行或者这一列是 回文 的。你可以将 grid
中任意格子的值 翻转 ,也就是将格子里的值从 0
变成 1
,或者从 1
变成 0
。请你返回 最少 翻转次数,使得矩阵 要么 所有行是 回文的 ,要么所有列是 回文的 。
示例 1:
输入:grid = [[1,0,0],[0,0,0],[0,0,1]]
输出:2
解题思路:
这段代码的目的是找出将一个二维矩阵 grid
中的所有元素变成相同值所需的最小翻转次数。翻转可以是按行翻转或按列翻转。代码的思路可以分解为以下几个步骤:
- 初始化变量:
m
存储矩阵的行数(gridSize
)。n
存储矩阵的列数(gridColSize[0]
,假设所有列的长度相同)。rowFlips
和colFlips
分别用于记录按行翻转和按列翻转的次数。
- 计算按行翻转的次数:
- 遍历矩阵的每一行(
for (int i = 0; i < m; i++)
)。 - 对于每一行,使用两个指针
j1
和j2
分别从行的开始和结束向中间遍历(for (int j1 = 0, j2 = n - 1; j1 < j2; j1++, j2--)
)。 - 如果对应位置上的元素不相等(
if (grid[i][j1] != grid[i][j2])
),则说明这一行需要通过翻转来使得所有元素相同。每次发现不相等时,rowFlips
加一。
- 遍历矩阵的每一行(
- 计算按列翻转的次数:
- 遍历矩阵的每一列(
for (int j = 0; j < n; j++)
)。 - 对于每一列,使用两个指针
i1
和i2
分别从列的开始和结束向中间遍历(for (int i1 = 0, i2 = m - 1; i1 < i2; i1++, i2--)
)。 - 如果对应位置上的元素不相等(
if (grid[i1][j] != grid[i2][j])
),则说明这一列需要通过翻转来使得所有元素相同。每次发现不相等时,colFlips
加一。
- 遍历矩阵的每一列(
- 返回最小翻转次数:
- 最后,使用
fmin(rowFlips, colFlips)
返回按行翻转和按列翻转中的较小次数,即为将整个矩阵的所有元素变成相同值所需的最小翻转次数。
- 最后,使用
int minFlips(int** grid, int gridSize, int* gridColSize) {
int m = gridSize, n = gridColSize[0];
int rowFlips = 0;
for (int i = 0; i < m; i++) {
for (int j1 = 0, j2 = n - 1; j1 < j2; j1++, j2--) {
if (grid[i][j1] != grid[i][j2]) {
rowFlips++;
}
}
}
int colFlips = 0;
for (int j = 0; j < n; j++) {
for (int i1 = 0, i2 = m - 1; i1 < i2; i1++, i2--) {
if (grid[i1][j] != grid[i2][j]) {
colFlips++;
}
}
}
return fmin(rowFlips, colFlips);
}
总结
- 代码首先计算了将所有行元素变成相同值所需的最少按行翻转次数。
- 然后计算了将所有列元素变成相同值所需的最少按列翻转次数。
- 最后返回了这两种翻转方式中的最小次数。这种方法的思路是基于观察:如果一行或一列中有不相等的元素,那么通过一次翻转可以使得这一行或列的所有元素相同。通过比较所有行和所有列所需的最小翻转次数,可以得到整个矩阵所需的最小翻转次数。