
Input: grid =[[1,1,1],[1,1,1],[0,1,0]]Output: 2Explanation:
In the first operation, change all cell values of row 1 and column 1 to zero.In the second operation, change all cell values of row 0 and column 0 to zero.
Example 2:
1
2
3
4
5
6
7

Input: grid =[[0,1,0],[1,0,1],[0,1,0]]Output: 2Explanation:
In the first operation, change all cell values of row 1 and column 0 to zero.In the second operation, change all cell values of row 2 and column 1 to zero.Note that we cannot perform an operation using row 1 and column 1 because grid[1][1]!=1.
Example 3:
1
2
3
4
5

Input: grid =[[0,0],[0,0]]Output: 0Explanation:
There are no 1's to remove so return0.
Since the grid is small (at most 15 cells), we can represent the entire grid as a bitmask (an integer). Each operation zeroes out a row and a column if the cell is 1, so we can use BFS to find the minimum number of operations to reach the all-zero state.
classSolution {
public:int removeOnes(vector<vector<int>>& grid) {
int m = grid.size(), n = grid[0].size();
int total = m * n;
int start =0;
for (int i =0; i < m; ++i)
for (int j =0; j < n; ++j)
if (grid[i][j]) start |= (1<< (i * n + j));
queue<pair<int, int>> q;
unordered_set<int> vis;
q.push({start, 0});
vis.insert(start);
while (!q.empty()) {
auto [mask, step] = q.front(); q.pop();
if (mask ==0) return step;
for (int i =0; i < m; ++i) {
for (int j =0; j < n; ++j) {
if (!(mask & (1<< (i * n + j)))) continue;
int nmask = mask;
for (int k =0; k < n; ++k) nmask &=~(1<< (i * n + k));
for (int k =0; k < m; ++k) nmask &=~(1<< (k * n + j));
if (!vis.count(nmask)) {
vis.insert(nmask);
q.push({nmask, step +1});
}
}
}
}
return-1;
}
};
import java.util.*;
classSolution {
publicintremoveOnes(int[][] grid) {
int m = grid.length, n = grid[0].length, total = m * n;
int start = 0;
for (int i = 0; i < m; ++i)
for (int j = 0; j < n; ++j)
if (grid[i][j]== 1) start |= (1 << (i * n + j));
Queue<int[]> q =new LinkedList<>();
Set<Integer> vis =new HashSet<>();
q.offer(newint[]{start, 0});
vis.add(start);
while (!q.isEmpty()) {
int[] cur = q.poll();
int mask = cur[0], step = cur[1];
if (mask == 0) return step;
for (int i = 0; i < m; ++i) {
for (int j = 0; j < n; ++j) {
if ((mask & (1 << (i * n + j))) == 0) continue;
int nmask = mask;
for (int k = 0; k < n; ++k) nmask &=~(1 << (i * n + k));
for (int k = 0; k < m; ++k) nmask &=~(1 << (k * n + j));
if (!vis.contains(nmask)) {
vis.add(nmask);
q.offer(newint[]{nmask, step + 1});
}
}
}
}
return-1;
}
}
import java.util.*
classSolution {
funremoveOnes(grid: Array<IntArray>): Int {
val m = grid.size
val n = grid[0].size
val total = m * n
var start = 0for (i in0 until m)
for (j in0 until n)
if (grid[i][j] ==1) start = start or (1 shl (i * n + j))
val q: Queue<Pair<Int, Int>> = LinkedList()
val vis = mutableSetOf<Int>()
q.offer(Pair(start, 0))
vis.add(start)
while (q.isNotEmpty()) {
val(mask, step) = q.poll()
if (mask ==0) return step
for (i in0 until m) {
for (j in0 until n) {
if ((mask and (1 shl (i * n + j))) ==0) continuevar nmask = mask
for (k in0 until n) nmask = nmask and (1 shl (i * n + k)).inv()
for (k in0 until m) nmask = nmask and (1 shl (k * n + j)).inv()
if (nmask !in vis) {
vis.add(nmask)
q.offer(Pair(nmask, step + 1))
}
}
}
}
return -1 }
}
from collections import deque
classSolution:
defremoveOnes(self, grid: list[list[int]]) -> int:
m, n = len(grid), len(grid[0])
start =0for i in range(m):
for j in range(n):
if grid[i][j]:
start |=1<< (i * n + j)
q = deque([(start, 0)])
vis = {start}
while q:
mask, step = q.popleft()
if mask ==0:
return step
for i in range(m):
for j in range(n):
ifnot (mask & (1<< (i * n + j))):
continue nmask = mask
for k in range(n):
nmask &=~(1<< (i * n + k))
for k in range(m):
nmask &=~(1<< (k * n + j))
if nmask notin vis:
vis.add(nmask)
q.append((nmask, step +1))
return-1
use std::collections::{VecDeque, HashSet};
impl Solution {
pubfnremove_ones(grid: Vec<Vec<i32>>) -> i32 {
let m = grid.len();
let n = grid[0].len();
letmut start =0;
for i in0..m {
for j in0..n {
if grid[i][j] ==1 {
start |=1<< (i * n + j);
}
}
}
letmut q = VecDeque::new();
letmut vis = HashSet::new();
q.push_back((start, 0));
vis.insert(start);
whilelet Some((mask, step)) = q.pop_front() {
if mask ==0 { return step; }
for i in0..m {
for j in0..n {
if mask & (1<< (i * n + j)) ==0 { continue; }
letmut nmask = mask;
for k in0..n { nmask &=!(1<< (i * n + k)); }
for k in0..m { nmask &=!(1<< (k * n + j)); }
if!vis.contains(&nmask) {
vis.insert(nmask);
q.push_back((nmask, step +1));
}
}
}
}
-1 }
}