Talentd
FleetCode
Make and follow sheets.Sign in

Minimum Number of Flips to Convert Binary Matrix to Zero Matrix solution and explanation

HardArrayBit ManipulationBreadth-First SearchHash Table9 min read72.9% acceptanceUpdated 9 Apr 2026
Leetcode 1284. Minimum Number of Flips to Convert Binary Matrix to Zero MatrixAlgorithms for Big Bucks · 10:09 · 3K viewsWatch on YouTube
9 more videos on this problem
  1. Leetcode 1284. Minimum Number of Flips to Convert Binary Matrix to Zero MatrixAlgorithms for Big Bucks · 10:09 · 3K views
  2. Minimum Number of Flips to Convert Binary Matrix to Zero Matrix | Leetcode 1284 | BFSNavyaa Sharma · 28:39 · 2K views
  3. 花花酱 LeetCode 1284. Minimum Number of Flips to Convert Binary Matrix to Zero - 刷题找工作 EP283Hua Hua · 13:51 · 2K views
  4. Leetcode 1284 Minimum Number of Flips to Convert Binary Matrix to Zero Matrix - Hard QuestionAlgorithmicIQ · 32:29 · 928 views
  5. 【每日一题】1284. Minimum Number of Flips to Convert Binary Matrix to Zero Matrix, 11/27/2020Huifeng Guan · 27:11 · 783 views
  6. Daily Code Challenge 1 - Minimum Number of Flips to Convert Binary Matrix to Zero MatrixSoftware the Hard Way · 54:36 · 617 views
  7. Leetcode 1284. Minimum Number of Flips to Convert Binary Matrix to Zero MatrixFearless Learner · 8:55 · 484 views
  8. Leetcode 1284. Minimum Number of Flips to Convert Binary Matrix to Zero Matrix (bit mask)LetsCode · 22:07 · 354 views
  9. Minimum Number of Flips to Convert Binary Matrix to Zero Matrix #leetcode #1284 easy solutionCoding Champs · 7:44 · 341 views
  10. No Sound Leetcode 1284: Minimum Number of Flips to Convert Binary Matrix to Zero MatrixExtremeProgrammer · 5:07 · 9 views

The problem

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.

Approach overview

Problem Overview: You are given an m x n binary matrix. Flipping a cell toggles that cell and its four neighbors (up, down, left, right). The goal is to reach an all-zero matrix using the minimum number of flips. If no sequence of flips produces a zero matrix, return -1.

Approach 1: Breadth-First Search with Bitmask Encoding (Time: O(2^(m*n)), Space: O(2^(m*n)))

The matrix state can be compressed into a single integer using bit manipulation. Each bit represents a cell. A flip operation toggles the corresponding bit and the bits for its neighbors. Starting from the initial state, run Breadth-First Search across all reachable states. BFS guarantees the first time you reach the zero mask is the minimum number of flips. Use a visited set to avoid revisiting states. This works well because the matrix size is small (at most 3x3), so the state space is bounded by 2^(m*n).

Approach 2: BFS with Matrix State Encoding (Time: O(2^(m*n) * m * n), Space: O(2^(m*n)))

Instead of compressing the grid into a bitmask, encode the matrix as a string or flattened array and store it in a queue for BFS. For every state, iterate through each cell and simulate a flip by toggling the cell and its neighbors inside the matrix. Each generated configuration becomes a new node in the search graph. A hash set tracks visited configurations. This approach is easier to reason about but slower due to repeated matrix copying and string construction.

Approach 3: DFS with Iterative Deepening (Time: O(b^d) worst case, Space: O(d))

Depth-First Search with iterative deepening tries all flip sequences up to a certain depth, then increases the depth limit. Each recursive step chooses a cell to flip and updates the matrix state. If the matrix becomes all zeros within the depth bound, the search stops. DFS uses less memory than BFS because it only keeps the current path in the call stack. However, it may revisit equivalent states and tends to be slower for this problem due to the branching factor of m * n.

Recommended for interviews: BFS with bitmask encoding is the expected solution. It shows you recognize that the matrix state space is small and can be modeled as a graph where each node is a configuration. Encoding the grid into an integer dramatically reduces memory usage and makes state transitions efficient. Interviewers typically expect BFS plus bit manipulation rather than raw matrix copying.

Approach 1: Breadth-First Search with Bitmask Encoding

Breadth-First Search with Bitmask Encoding: In this approach, we use a BFS to explore all possible states of the matrix, representing each state as a bitmask. Each bit in the bitmask represents a cell in the matrix, allowing us to efficiently keep track of visited states. Starting from the initial matrix configuration, we flip each cell and its neighbors, transforming the state and pushing it into our BFS queue. By marking visited states, we avoid cycles and redundant operations. We continue this process until we either find a zero matrix or exhaust all possibilities, at which point we return -1.

from collections import deque

class Solution:
    def minFlips(self, mat):
        def flip(bitmask, r, c):
            n, m = len(mat), len(mat[0])
            for i, j in [(r, c), (r+1, c), (r-1, c), (r, c+1), (r, c-1)]:
                if 0 <= i < n and 0 <= j < m:
                    bitmask ^= (1 << (i * m + j))
            return bitmask

        n, m = len(mat), len(mat[0])
        start = 0
        for i in range(n):
            for j in range(m):
                if mat[i][j]:
                    start |= (1 << (i * m + j))

        queue = deque([(start, 0)])
        visited = set()
        visited.add(start)

        while queue:
            bitmask, steps = queue.popleft()
            if bitmask == 0:
                return steps
            for i in range(n):
                for j in range(m):
                    next_bitmask = flip(bitmask, i, j)
                    if next_bitmask not in visited:
                        visited.add(next_bitmask)
                        queue.append((next_bitmask, steps + 1))

        return -1
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Queue;

class Solution {
    private int flip(int bitmask, int r, int c, int n, int m) {
        for (int[] dir : new int[][]{{0, 0}, {1, 0}, {-1, 0}, {0, 1}, {0, -1}}) {
            int nr = r + dir[0], nc = c + dir[1];
            if (nr >= 0 && nr < n && nc >= 0 && nc < m) {
                bitmask ^= (1 << (nr * m + nc));
            }
        }
        return bitmask;
    }

    public int minFlips(int[][] mat) {
        int n = mat.length, m = mat[0].length;
        int start = 0;
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                if (mat[i][j] == 1) {
                    start |= (1 << (i * m + j));
                }
            }
        }

        Queue<int[]> queue = new LinkedList<>();
        HashSet<Integer> visited = new HashSet<>();
        queue.offer(new int[]{start, 0});
        visited.add(start);

        while (!queue.isEmpty()) {
            int[] node = queue.poll();
            int bitmask = node[0], steps = node[1];
            if (bitmask == 0) {
                return steps;
            }
            for (int i = 0; i < n; i++) {
                for (int j = 0; j < m; j++) {
                    int nextBitmask = flip(bitmask, i, j, n, m);
                    if (!visited.contains(nextBitmask)) {
                        visited.add(nextBitmask);
                        queue.offer(new int[]{nextBitmask, steps + 1});
                    }
                }
            }
        }
        return -1;
    }
}

Python BFS Explanation: We start by encoding the matrix into a single integer called a bitmask. Each bit in the integer represents a cell in the matrix. We use BFS to traverse all possible flips in the matrix, starting from the initial configuration. If a state reaches a zero matrix (bitmask == 0), we return the number of steps taken. We track visited states to avoid reprocessing states.

Complexity

Complexity: Time Complexity: O(N * 2^(M*N)), where N is the number of cells, as we are exploring all possible states. Space Complexity: O(2^(M*N)) for the visited set and queue.

Try this approach in the editor

Approach 2: Breadth-First Search (BFS) with State Encoding

The problem can be tackled using a Breadth-First Search (BFS) approach, where we treat each matrix state as a node in a graph. The challenge is to explore all possible ways to make the minimum number of transformations from the initial matrix to a zero matrix. To efficiently manage and transition between states, we encode the matrix as a bitmask. Each state represents a particular configuration of the matrix.

Every time we flip a cell, it impacts the cell itself and its neighbors. For each state, we systematically toggle each cell and add the new resulting state to the BFS queue, marking states as visited to prevent redundant checks.

from collections import deque

def min_flips(mat):
    m, n = len(mat), len(mat[0])

    def mat_to_bits(mat):
        bits = 0
        for i in range(m):
            for j in range(n):
                bits |= mat[i][j] << (i * n + j)
        return bits

    def bits_to_mat(bits):
        return [[(bits >> (i * n + j)) & 1 for j in range(n)] for i in range(m)]

    def flip(bit_map, i, j):
        directions = [(0, 0), (0, 1), (1, 0), (0, -1), (-1, 0)]
        for di, dj in directions:
            ni, nj = i + di, j + dj
            if 0 <= ni < m and 0 <= nj < n:
                bit_map ^= 1 << (ni * n + nj)
        return bit_map

    start = mat_to_bits(mat)
    if start == 0:
        return 0

    queue = deque([(start, 0)])
    visited = {start}

    while queue:
        state, step = queue.popleft()
        for i in range(m):
            for j in range(n):
                new_state = flip(state, i, j)
                if new_state == 0:
                    return step + 1
                if new_state not in visited:
                    visited.add(new_state)
                    queue.append((new_state, step + 1))

    return -1
#include <vector>
#include <queue>
#include <unordered_set>
using namespace std;

class Solution {
public:
    int minFlips(vector<vector<int>>& mat) {
        int m = mat.size(), n = mat[0].size();

        auto matToBits = [&](const vector<vector<int>>& mat) {
            int bits = 0;
            for (int i = 0; i < m; ++i) {
                for (int j = 0; j < n; ++j) {
                    bits |= (mat[i][j] << (i * n + j));
                }
            }
            return bits;
        };

        function<int(int,int)> flip = [&](int bits, int i, int j) {
            vector<pair<int, int>> directions = {{0, 0}, {0, 1}, {1, 0}, {0, -1}, {-1, 0}};
            for (auto& [di, dj] : directions) {
                int ni = i + di, nj = j + dj;
                if (0 <= ni && ni < m && 0 <= nj && nj < n) {
                    bits ^= 1 << (ni * n + nj);
                }
            }
            return bits;
        };

        int start = matToBits(mat);
        if (start == 0) return 0;

        queue<pair<int, int>> q;
        unordered_set<int> visited;
        q.emplace(start, 0);
        visited.insert(start);

        while (!q.empty()) {
            auto [state, step] = q.front();
            q.pop();
            for (int i = 0; i < m; ++i) {
                for (int j = 0; j < n; ++j) {
                    int newState = flip(state, i, j);
                    if (newState == 0) return step + 1;
                    if (visited.insert(newState).second) {
                        q.emplace(newState, step + 1);
                    }
                }
            }
        }

        return -1;
    }
};

This Python solution uses a BFS strategy to examine states derived from flipping cells, leveraging bit manipulation to represent matrix configurations. 'mat_to_bits' encodes the matrix state to an integer, while 'bits_to_mat' decodes it back. The function 'flip' updates the bit representation by toggling the cell and its neighbors. The BFS explores all possible states, maintaining a queue and a set for visited states to prevent duplicate work. The method returns the number of flips needed or -1 if conversion isn't feasible.

Complexity

Time Complexity: O(2^(m*n) * m * n). We consider all possible matrix states (2^(m*n)). Each state performs an O(m*n) flip operation.
Space Complexity: O(2^(m*n)). We need space for the queue and visited set, each holding up to 2^(m*n) states.

Try this approach in the editor

Approach 3: Depth-First Search (DFS) with Iterative Deepening

An alternative approach to solving the problem is through Depth-First Search (DFS) with Iterative Deepening. In this method, we explore the state space in a systematic and recursive manner, delving deeper into each potential flip configuration. We begin with a depth limit and increment gradually, attempting not to exceed this limit. The matrix state is represented at each node recursively, experimenting with each cell-flip combination.

The DFS pathway explores all configurations actively till terminal state clearance (zero matrix or true end-node) is discovered or edge constraints reach limits.

import java.util.HashSet;
import java.util.Set;

public class Solution {
    private final int[][] directions = {{0, 0}, {0, 1}, {1, 0}, {0, -1}, {-1, 0}};

    public int minFlips(int[][] mat) {
        int m = mat.length, n = mat[0].length;
        int start = matToBits(mat);
        if (start == 0) return 0;

        for (int depth = 1;; depth++) {
            if (dfs(start, 0, depth, new HashSet<>(), m, n)) {
                return depth;
            }
        }
    }

    private int matToBits(int[][] mat) {
        int m = mat.length, n = mat[0].length, bits = 0;
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                bits |= mat[i][j] << (i * n + j);
            }
        }
        return bits;
    }

    private int flip(int bits, int i, int j, int m, int n) {
        for (int[] d : directions) {
            int ni = i + d[0], nj = j + d[1];
            if (0 <= ni && ni < m && 0 <= nj && nj < n) {
                bits ^= (1 << (ni * n + nj));
            }
        }
        return bits;
    }

    private boolean dfs(int state, int depth, int maxDepth, Set<Integer> visited, int m, int n) {
        if (depth == maxDepth && state == 0) return true;
        if (depth < maxDepth) {
            visited.add(state);
            for (int i = 0; i < m; i++) {
                for (int j = 0; j < n; j++) {
                    int newState = flip(state, i, j, m, n);
                    if (!visited.contains(newState)) {
                        if (dfs(newState, depth + 1, maxDepth, visited, m, n)) {
                            return true;
                        }
                    }
                }
            }
            visited.remove(state);
        }
        return false;
    }
}

This Java implementation employs an iterative deepening DFS. We maintain a depth-bound search, recursing deeply till reaching the current depth limit. 'dfs()' explores flipping combinations, checking at each step whether a zero matrix configuration is achievable within constraints. 'matToBits()' and 'flip()' manage state representation, while checking reached states recursively using a visited set to prevent repetition.

Complexity

Time Complexity: Exponential in the number of matrix cells in the worst case, due to exhaustive state exploration.
Space Complexity: O(2^(m*n)) due to recursion depth and visited set overhead.

Try this approach in the editor

Approach 4: Default Approach

func minFlips(mat [][]int) int {
	m, n := len(mat), len(mat[0])
	state := 0
	for i, row := range mat {
		for j, v := range row {
			if v == 1 {
				state |= 1 << (i*n + j)
			}
		}
	}
	q := []int{state}
	vis := map[int]bool{state: true}
	ans := 0
	dirs := []int{0, -1, 0, 1, 0, 0}
	for len(q) > 0 {
		for t := len(q); t > 0; t-- {
			state = q[0]
			if state == 0 {
				return ans
			}
			q = q[1:]
			for i := 0; i < m; i++ {
				for j := 0; j < n; j++ {
					nxt := state
					for k := 0; k < 5; k++ {
						x, y := i+dirs[k], j+dirs[k+1]
						if x < 0 || x >= m || y < 0 || y >= n {
							continue
						}
						if (nxt & (1 << (x*n + y))) != 0 {
							nxt -= 1 << (x*n + y)
						} else {
							nxt |= 1 << (x*n + y)
						}
					}
					if !vis[nxt] {
						vis[nxt] = true
						q = append(q, nxt)
					}
				}
			}
		}
		ans++
	}
	return -1
}
Try this approach in the editor

Complexity comparison

ApproachComplexity
Breadth-First Search with Bitmask Encoding

Complexity: Time Complexity: O(N * 2^(M*N)), where N is the number of cells, as we are exploring all possible states. Space Complexity: O(2^(M*N)) for the visited set and queue.

Breadth-First Search (BFS) with State Encoding

Time Complexity: O(2^(m*n) * m * n). We consider all possible matrix states (2^(m*n)). Each state performs an O(m*n) flip operation.
Space Complexity: O(2^(m*n)). We need space for the queue and visited set, each holding up to 2^(m*n) states.

Depth-First Search (DFS) with Iterative Deepening

Time Complexity: Exponential in the number of matrix cells in the worst case, due to exhaustive state exploration.
Space Complexity: O(2^(m*n)) due to recursion depth and visited set overhead.

Default Approach–

Complexity analysis

ApproachTimeSpaceWhen to Use
BFS with Bitmask EncodingO(2^(m*n))O(2^(m*n))Best overall approach when matrix size is small and states can be compressed into a bitmask
BFS with Matrix State EncodingO(2^(m*n) * m * n)O(2^(m*n))Useful when bit manipulation is avoided or when clarity is preferred over performance
DFS with Iterative DeepeningO(b^d)O(d)Memory-constrained scenarios or when exploring bounded search depth

Frequently asked questions

Is Minimum Number of Flips to Convert Binary Matrix to Zero Matrix easy or hard?

Minimum Number of Flips to Convert Binary Matrix to Zero Matrix is classified as Hard. The difficulty comes from recognizing the problem as a graph search over matrix states and implementing efficient state encoding using bit manipulation.

Minimum Number of Flips to Convert Binary Matrix to Zero Matrix Python/Java solution

Python and Java implementations typically encode the matrix as a bitmask integer and run BFS over possible states. Each step toggles the current cell and its neighbors using XOR operations. The queue tracks states with their flip counts until the zero mask is reached or all states are explored.

How to solve Minimum Number of Flips to Convert Binary Matrix to Zero Matrix in O(n)?

An O(n) solution does not exist for the general problem because every matrix configuration may need to be explored. The practical optimal solution models the matrix as a graph of states and runs BFS over encoded states. Using bitmask compression keeps transitions fast and avoids large memory overhead.

What is the best approach for Minimum Number of Flips to Convert Binary Matrix to Zero Matrix?

Breadth-First Search with bitmask state encoding is the most efficient approach. The matrix is encoded into an integer where each bit represents a cell. BFS explores all reachable states and guarantees the first time the zero matrix appears is the minimum number of flips. Time complexity is O(2^(m*n)) with the same order of space.

Is Minimum Number of Flips to Convert Binary Matrix to Zero Matrix asked at Google/Amazon/Meta?

Grid state search problems using BFS and bitmasking frequently appear in interviews at companies like Google, Amazon, and Meta. This problem tests graph modeling, state compression, and shortest-path reasoning, which are common themes in technical interviews.

What data structure is used in Minimum Number of Flips to Convert Binary Matrix to Zero Matrix?

The solution primarily uses a queue for Breadth-First Search and a hash set to track visited states. Many optimized implementations also use integers as bitmasks to encode the matrix. This combines graph traversal with bit manipulation for efficient state transitions.

What is the time complexity of Minimum Number of Flips to Convert Binary Matrix to Zero Matrix?

The optimal BFS solution runs in O(2^(m*n)) time because each matrix configuration is treated as a state in a graph. For a 3x3 grid there are at most 512 states, which keeps the search manageable. Space complexity is also O(2^(m*n)) for the visited set and queue.

Comments

Now write it yourselfClose this page and solve Minimum Number of Flips to Convert Binary Matrix to Zero Matrix in the editor, without looking.
Practise Minimum Number of Flips to Convert Binary Matrix to Zero Matrix