转化为全零矩阵的最少反转次数Java
文章发布较早,内容可能过时,阅读注意甄别。
# 题目
给你一个 m x n 的二进制矩阵 mat。每一步,你可以选择一个单元格并将它反转(反转表示 0 变 1 ,1 变 0 )。如果存在和它相邻的单元格,那么这些相邻的单元格也会被反转。相邻的两个单元格共享同一条边。
请你返回将矩阵 mat 转化为全零矩阵的最少反转次数,如果无法转化为全零矩阵,请返回 -1 。
二进制矩阵 的每一个格子要么是 0 要么是 1 。
全零矩阵 是所有格子都为 0 的矩阵。
示例 1:
输入:mat = [[0,0],[0,1]]
输出:3
解释:一个可能的解是反转 (1, 0),然后 (0, 1) ,最后是 (1, 1) 。
示例 2:
输入:mat = [[0]]
输出:0
解释:给出的矩阵是全零矩阵,所以你不需要改变它。
示例 3:
输入:mat = [[1,0,0],[1,0,0]]
输出:-1
解释:该矩阵无法转变成全零矩阵
提示:
- m == mat.length
- n == mat[0].length
- 1 <= m <= 3
- 1 <= n <= 3
- mat[i][j] 是 0 或 1 。
# 思路
全零矩阵
# 解法
class Solution {
int m, n;
int ans = 10;
int[][] dir = new int[][]{{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
public int minFlips(int[][] mat) {
m = mat.length;
n = mat[0].length;
// 1 的个数
int diff = 0;
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (mat[i][j] == 1) {
diff++;
}
}
}
dfs(mat, 0, 0, diff, 0);
if (ans == 10) {
return -1;
} else {
return ans;
}
}
public void dfs(int[][] mat, int i, int j, int diff, int cnt) {
// j = n 代表进入列数的边界,转换坐标并重新进入递归
// i 变为下一行,j 变为第一列
if (j == n) {
j = 0;
i = i + 1;
dfs(mat, i, j, diff, cnt);
return;
}
// 找到全零矩阵,更新答案,结束递归
if (diff == 0) {
ans = Math.min(ans, cnt);
return;
}
// i = m 代表遍历完单元格,结束递归
if (i == m) {
return;
}
// newDiff 为异或产生的影响,即 1 的个数变化
int newDiff = help(mat, i, j);
dfs(mat, i, j + 1, diff + newDiff, cnt + 1);
// 再次异或,消除影响
help(mat, i, j);
dfs(mat, i, j + 1, diff, cnt);
}
// 反转 (i,j) 以及相邻单元格,并获取 1 的个数变化
public int help(int[][] mat, int i, int j) {
// cnt 为 1 的个数变化
int cnt = 0;
if (mat[i][j] == 0) {
cnt++;
} else {
cnt--;
}
mat[i][j] = 1 - mat[i][j];
// 遍历相邻单元格
for (int[] d : dir) {
int nx = i + d[0], ny = j + d[1];
if (nx < 0 || nx >= m || ny < 0 || ny >= n) {
continue;
}
if (mat[nx][ny] == 0) {
cnt++;
} else {
cnt--;
}
mat[nx][ny] = 1 - mat[nx][ny];
}
return cnt;
}}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# 总结
- 分析出几种情况,然后分别对各个情况实现