Skip to content

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 either 0 or 1.

 

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;
};

Released under the MIT license