1284. Minimum Number of Flips to Convert Binary Matrix to Zero Matrix
Description
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 do not need to change it.
Example 3:
Input: mat = [[1,0,0],[1,0,0]] Output: -1 Explanation: Given matrix cannot be a zero matrix.
Constraints:
m == mat.length
n == mat[i].length
1 <= m, n <= 3
mat[i][j]
is either0
or1
.
Solutions
Solution: Breadth-First Search + Bit Manipulation
- Time complexity: O(2mn*mn)
- Space complexity: O(2mn)
JavaScript
js
/**
* @param {number[][]} mat
* @return {number}
*/
const minFlips = function (mat) {
const m = mat.length;
const n = mat[0].length;
const visited = new Set();
let originBitmask = 0;
const getBitmask = (row, col) => 1 << (row * n + col);
for (let row = 0; row < m; row++) {
for (let col = 0; col < n; col++) {
const value = mat[row][col];
if (!value) continue;
originBitmask |= getBitmask(row, col);
}
}
if (!originBitmask) return 0;
let queue = [originBitmask];
let result = 0;
const flipMatrix = (row, col, bitmask) => {
bitmask ^= getBitmask(row, col);
if (row - 1 >= 0) bitmask ^= getBitmask(row - 1, col);
if (row + 1 < m) bitmask ^= getBitmask(row + 1, col);
if (col - 1 >= 0) bitmask ^= getBitmask(row, col - 1);
if (col + 1 < n) bitmask ^= getBitmask(row, col + 1);
return bitmask;
};
visited.add(originBitmask);
while (queue.length) {
const nextQueue = [];
result += 1;
for (const bitmask of queue) {
for (let row = 0; row < m; row++) {
for (let col = 0; col < n; col++) {
const nextBitmask = flipMatrix(row, col, bitmask);
if (!nextBitmask) return result;
if (visited.has(nextBitmask)) continue;
nextQueue.push(nextBitmask);
visited.add(nextBitmask);
}
}
}
queue = nextQueue;
}
return -1;
};