Off-by-one on range boundaries
Wrong move: Loop endpoints miss first/last candidate.
Usually fails on: Fails on minimal arrays and exact-boundary answers.
Fix: Re-derive loops from inclusive/exclusive ranges before coding.
Break down a hard problem into reliable checkpoints, edge-case handling, and complexity trade-offs.
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.lengthn == mat[i].length1 <= m, n <= 3mat[i][j] is either 0 or 1.Problem summary: 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.
Start with the most direct exhaustive search. That gives a correctness anchor before optimizing.
Pattern signal: Array · Hash Map · Bit Manipulation
[[0,0],[0,1]]
[[0]]
[[1,0,0],[1,0,0]]
minimum-operations-to-remove-adjacent-ones-in-matrix)remove-all-ones-with-row-and-column-flips)remove-all-ones-with-row-and-column-flips-ii)Source-backed implementations are provided below for direct study and interview prep.
// Accepted solution for LeetCode #1284: Minimum Number of Flips to Convert Binary Matrix to Zero Matrix
class Solution {
public int minFlips(int[][] mat) {
int m = mat.length, n = mat[0].length;
int state = 0;
for (int i = 0; i < m; ++i) {
for (int j = 0; j < n; ++j) {
if (mat[i][j] == 1) {
state |= 1 << (i * n + j);
}
}
}
Deque<Integer> q = new ArrayDeque<>();
q.offer(state);
Set<Integer> vis = new HashSet<>();
vis.add(state);
int ans = 0;
int[] dirs = {0, -1, 0, 1, 0, 0};
while (!q.isEmpty()) {
for (int t = q.size(); t > 0; --t) {
state = q.poll();
if (state == 0) {
return ans;
}
for (int i = 0; i < m; ++i) {
for (int j = 0; j < n; ++j) {
int nxt = state;
for (int k = 0; k < 5; ++k) {
int x = i + dirs[k], y = 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.contains(nxt)) {
vis.add(nxt);
q.offer(nxt);
}
}
}
}
++ans;
}
return -1;
}
}
// Accepted solution for LeetCode #1284: Minimum Number of Flips to Convert Binary Matrix to Zero Matrix
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
}
# Accepted solution for LeetCode #1284: Minimum Number of Flips to Convert Binary Matrix to Zero Matrix
class Solution:
def minFlips(self, mat: List[List[int]]) -> int:
m, n = len(mat), len(mat[0])
state = sum(1 << (i * n + j) for i in range(m) for j in range(n) if mat[i][j])
q = deque([state])
vis = {state}
ans = 0
dirs = [0, -1, 0, 1, 0, 0]
while q:
for _ in range(len(q)):
state = q.popleft()
if state == 0:
return ans
for i in range(m):
for j in range(n):
nxt = state
for k in range(5):
x, y = i + dirs[k], j + dirs[k + 1]
if not 0 <= x < m or not 0 <= y < n:
continue
if nxt & (1 << (x * n + y)):
nxt -= 1 << (x * n + y)
else:
nxt |= 1 << (x * n + y)
if nxt not in vis:
vis.add(nxt)
q.append(nxt)
ans += 1
return -1
// Accepted solution for LeetCode #1284: Minimum Number of Flips to Convert Binary Matrix to Zero Matrix
struct Solution;
impl Solution {
fn min_flips(mut mat: Vec<Vec<i32>>) -> i32 {
let n = mat.len();
let m = mat[0].len();
let mut res = std::usize::MAX;
Self::dfs(0, 0, &mut mat, &mut res, n, m);
if res == std::usize::MAX {
-1
} else {
res as i32
}
}
fn dfs(start: usize, k: usize, mat: &mut Vec<Vec<i32>>, min: &mut usize, n: usize, m: usize) {
if start == n * m {
if Self::ones(mat, n, m) == 0 {
*min = (*min).min(k);
}
} else {
let r = start / m;
let c = start % m;
Self::flip(r, c, mat, n, m);
Self::dfs(start + 1, k + 1, mat, min, n, m);
Self::flip(r, c, mat, n, m);
Self::dfs(start + 1, k, mat, min, n, m);
}
}
fn flip(i: usize, j: usize, mat: &mut Vec<Vec<i32>>, n: usize, m: usize) {
mat[i][j] = 1 - mat[i][j];
if i > 0 {
mat[i - 1][j] = 1 - mat[i - 1][j];
}
if j > 0 {
mat[i][j - 1] = 1 - mat[i][j - 1];
}
if i + 1 < n {
mat[i + 1][j] = 1 - mat[i + 1][j];
}
if j + 1 < m {
mat[i][j + 1] = 1 - mat[i][j + 1];
}
}
fn ones(mat: &[Vec<i32>], n: usize, m: usize) -> usize {
let mut res = 0;
for i in 0..n {
for j in 0..m {
if mat[i][j] == 1 {
res += 1;
}
}
}
res
}
}
#[test]
fn test() {
let mat = vec_vec_i32![[0, 0], [0, 1]];
let res = 3;
assert_eq!(Solution::min_flips(mat), res);
let mat = vec_vec_i32![[0]];
let res = 0;
assert_eq!(Solution::min_flips(mat), res);
let mat = vec_vec_i32![[1, 1, 1], [1, 0, 1], [0, 0, 0]];
let res = 6;
assert_eq!(Solution::min_flips(mat), res);
let mat = vec_vec_i32![[1, 0, 0], [1, 0, 0]];
let res = -1;
assert_eq!(Solution::min_flips(mat), res);
}
// Accepted solution for LeetCode #1284: Minimum Number of Flips to Convert Binary Matrix to Zero Matrix
// Auto-generated TypeScript example from java.
function exampleSolution(): void {
}
// Reference (java):
// // Accepted solution for LeetCode #1284: Minimum Number of Flips to Convert Binary Matrix to Zero Matrix
// class Solution {
// public int minFlips(int[][] mat) {
// int m = mat.length, n = mat[0].length;
// int state = 0;
// for (int i = 0; i < m; ++i) {
// for (int j = 0; j < n; ++j) {
// if (mat[i][j] == 1) {
// state |= 1 << (i * n + j);
// }
// }
// }
// Deque<Integer> q = new ArrayDeque<>();
// q.offer(state);
// Set<Integer> vis = new HashSet<>();
// vis.add(state);
// int ans = 0;
// int[] dirs = {0, -1, 0, 1, 0, 0};
// while (!q.isEmpty()) {
// for (int t = q.size(); t > 0; --t) {
// state = q.poll();
// if (state == 0) {
// return ans;
// }
// for (int i = 0; i < m; ++i) {
// for (int j = 0; j < n; ++j) {
// int nxt = state;
// for (int k = 0; k < 5; ++k) {
// int x = i + dirs[k], y = 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.contains(nxt)) {
// vis.add(nxt);
// q.offer(nxt);
// }
// }
// }
// }
// ++ans;
// }
// return -1;
// }
// }
Use this to step through a reusable interview workflow for this problem.
Sort the array in O(n log n), then scan for the missing or unique element by comparing adjacent pairs. Sorting requires O(n) auxiliary space (or O(1) with in-place sort but O(n log n) time remains). The sort step dominates.
Bitwise operations (AND, OR, XOR, shifts) are O(1) per operation on fixed-width integers. A single pass through the input with bit operations gives O(n) time. The key insight: XOR of a number with itself is 0, which eliminates duplicates without extra space.
Review these before coding to avoid predictable interview regressions.
Wrong move: Loop endpoints miss first/last candidate.
Usually fails on: Fails on minimal arrays and exact-boundary answers.
Fix: Re-derive loops from inclusive/exclusive ranges before coding.
Wrong move: Zero-count keys stay in map and break distinct/count constraints.
Usually fails on: Window/map size checks are consistently off by one.
Fix: Delete keys when count reaches zero.