class Solution {
public:
int minFlips(vector<vector<int>>& grid) {
}
};
100385. 最少翻转次数使二进制矩阵回文 II
给你一个 m x n
的二进制矩阵 grid
。
如果矩阵中一行或者一列从前往后与从后往前读是一样的,那么我们称这一行或者这一列是 回文 的。
你可以将 grid
中任意格子的值 翻转 ,也就是将格子里的值从 0
变成 1
,或者从 1
变成 0
。
请你返回 最少 翻转次数,使得矩阵中 所有 行和列都是 回文的 ,且矩阵中 1
的数目可以被 4
整除 。
示例 1:
输入:grid = [[1,0,0],[0,1,0],[0,0,1]]
输出:3
解释:
示例 2:
输入:grid = [[0,1],[0,1],[0,0]]
输出:2
解释:
示例 3:
输入:grid = [[1],[1]]
输出:2
解释:
提示:
m == grid.length
n == grid[i].length
1 <= m * n <= 2 * 105
0 <= grid[i][j] <= 1
原站题解
java 解法, 执行用时: 3 ms, 内存消耗: 93.7 MB, 提交时间: 2024-08-10 12:07:11
class Solution { public int minFlips(int[][] a) { int ans = 0; int m = a.length; int n = a[0].length; for (int i = 0; i < m / 2; i++) { for (int j = 0; j < n / 2; j++) { int cnt1 = a[i][j] + a[i][n - 1 - j] + a[m - 1 - i][j] + a[m - 1 - i][n - 1 - j]; ans += Math.min(cnt1, 4 - cnt1); // 全为 1 或全为 0 } } if (m % 2 > 0 && n % 2 > 0) { // 正中间的数必须是 0 ans += a[m / 2][n / 2]; } int diff = 0, cnt1 = 0; if (m % 2 > 0) { // 统计正中间这一排 for (int j = 0; j < n / 2; j++) { if (a[m / 2][j] != a[m / 2][n - 1 - j]) { diff++; } else { cnt1 += a[m / 2][j] * 2; } } } if (n % 2 > 0) { // 统计正中间这一列 for (int i = 0; i < m / 2; i++) { if (a[i][n / 2] != a[m - 1 - i][n / 2]) { diff++; } else { cnt1 += a[i][n / 2] * 2; } } } return ans + (diff > 0 ? diff : cnt1 % 4); } }
cpp 解法, 执行用时: 423 ms, 内存消耗: 189.2 MB, 提交时间: 2024-08-10 12:06:58
class Solution { public: int minFlips(vector<vector<int>>& a) { int m = a.size(), n = a[0].size(), ans = 0; for (int i = 0; i < m / 2; i++) { for (int j = 0; j < n / 2; j++) { int cnt1 = a[i][j] + a[i][n - 1 - j] + a[m - 1 - i][j] + a[m - 1 - i][n - 1 - j]; ans += min(cnt1, 4 - cnt1); // 全为 1 或全为 0 } } if (m % 2 && n % 2) { // 正中间的数必须是 0 ans += a[m / 2][n / 2]; } int diff = 0, cnt1 = 0; if (m % 2) { // 统计正中间这一排 for (int j = 0; j < n / 2; j++) { if (a[m / 2][j] != a[m / 2][n - 1 - j]) { diff++; } else { cnt1 += a[m / 2][j] * 2; } } } if (n % 2) { // 统计正中间这一列 for (int i = 0; i < m / 2; i++) { if (a[i][n / 2] != a[m - 1 - i][n / 2]) { diff++; } else { cnt1 += a[i][n / 2] * 2; } } } return ans + (diff ? diff : cnt1 % 4); } };
python3 解法, 执行用时: 238 ms, 内存消耗: 56.1 MB, 提交时间: 2024-08-10 12:06:41
class Solution: def minFlips(self, a: List[List[int]]) -> int: ans = 0 m, n = len(a), len(a[0]) for i in range(m // 2): row, row2 = a[i], a[-1 - i] for j in range(n // 2): cnt1 = row[j] + row[-1 - j] + row2[j] + row2[-1 - j] ans += min(cnt1, 4 - cnt1) # 全为 1 或全为 0 if m % 2 and n % 2: # 正中间的数必须是 0 ans += a[m // 2][n // 2] diff = cnt1 = 0 if m % 2: # 统计正中间这一排 row = a[m // 2] for j in range(n // 2): if row[j] != row[-1 - j]: diff += 1 else: cnt1 += row[j] * 2 if n % 2: # 统计正中间这一列 for i in range(m // 2): if a[i][n // 2] != a[- 1 - i][n // 2]: diff += 1 else: cnt1 += a[i][n // 2] * 2 return ans + (diff if diff else cnt1 % 4)
golang 解法, 执行用时: 290 ms, 内存消耗: 25.2 MB, 提交时间: 2024-08-10 12:06:26
func minFlips(a [][]int) (ans int) { m, n := len(a), len(a[0]) for i, row := range a[:m/2] { row2 := a[m-1-i] for j, x := range row[:n/2] { cnt1 := x + row[n-1-j] + row2[j] + row2[n-1-j] ans += min(cnt1, 4-cnt1) // 全为 1 或全为 0 } } if m%2 > 0 && n%2 > 0 { // 正中间的数必须是 0 ans += a[m/2][n/2] } diff, cnt1 := 0, 0 if m%2 > 0 { // 统计正中间这一排 row := a[m/2] for j, x := range row[:n/2] { if x != row[n-1-j] { diff++ } else { cnt1 += x * 2 } } } if n%2 > 0 { // 统计正中间这一列 for i, row := range a[:m/2] { if row[n/2] != a[m-1-i][n/2] { diff++ } else { cnt1 += row[n/2] * 2 } } } if diff > 0 { ans += diff } else { ans += cnt1 % 4 } return }