Given a m x n
binary matrix mat
. In one step, you can choose one cell and flip it and all the four neighbors of it if they exist (Flip is changing 1
to 0
and 0
to 1
). A pair of cells are called neighbors if they share one edge.
Return the minimum number of steps required to convert mat
to a zero matrix or -1
if you cannot.
A binary matrix is a matrix with all cells equal to 0
or 1
only.
A zero matrix is a matrix with all cells equal to 0
.
Example 1:
Input: mat = [[0,0],[0,1]] Output: 3 Explanation: One possible solution is to flip (1, 0) then (0, 1) and finally (1, 1) as shown.
Example 2:
Input: mat = [[0]] Output: 0 Explanation: Given matrix is a zero matrix. We don't need to change it.
Example 3:
Input: mat = [[1,1,1],[1,0,1],[0,0,0]] Output: 6
Example 4:
Input: mat = [[1,0,0],[1,0,0]] Output: -1 Explanation: Given matrix can't be a zero matrix
Constraints:
m == mat.length
n == mat[i].length
1 <= m, n <= 3
mat[i][j]
is either0
or1
.
题目链接:https://leetcode.com/problems/minimum-number-of-flips-to-convert-binary-matrix-to-zero-matrix/
题目大意:给一个01矩阵,每次选择一个位置,翻转其和上下左右位置,问变成全0最少多少步
题目分析: 数据范围实属搞笑,bfs即可,位运算hash
8ms,时间击败45.9% (其实这个数据范围可以推公式直接算翻转后的hash值)
class Solution {
private int[] dx = new int[] {1, 0, -1, 0};
private int[] dy = new int[] {0, 1, 0, -1};
private int getHash(int[][] mat) {
int ans = 0, n = mat.length, m = mat[0].length;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (mat[i][j] == 1) {
ans |= 1 << (i * m + j);
}
}
}
return ans;
}
class Step {
int cnt, hashVal;
int[][] mat;
Step(int cnt, int[][] mat) {
this.cnt = cnt;
this.mat = mat;
this.hashVal = getHash(mat);
}
}
public int minFlips(int[][] mat) {
int n = mat.length, m = mat[0].length;
Queue<Step> q = new LinkedList<>();
Set<Integer> set = new HashSet();
Step st = new Step(0, mat);
q.offer(st);
set.add(st.hashVal);
while (!q.isEmpty()) {
Step cur = q.poll();
if (cur.hashVal == 0) {
return cur.cnt;
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
int[][] nxtMat = new int[n][m];
for(int k = 0; k < cur.mat.length; k++){
nxtMat[k] = Arrays.copyOf(cur.mat[k], cur.mat[k].length);
}
nxtMat[i][j] = nxtMat[i][j] == 1 ? 0 : 1;
for (int k = 0; k < 4; k++) {
int xx = i + dx[k];
int yy = j + dy[k];
if (xx >= 0 && xx < n && yy >= 0 && yy < m) {
nxtMat[xx][yy] = nxtMat[xx][yy] == 1 ? 0 : 1;
}
}
Step nxt = new Step(cur.cnt + 1, nxtMat);
if (!set.contains(nxt.hashVal)) {
// System.out.println("cnt = "+ nxt.cnt);
// for (int x = 0; x < n; x++) {
// for (int y = 0; y < m; y++) {
// System.out.print(nxtMat[x][y] + " ");
// }
// System.out.println();
// }
// System.out.println();
set.add(nxt.hashVal);
q.add(nxt);
}
}
}
}
return -1;
}
}