给你一个 m x n 的二进制矩阵 mat。
每一步,你可以选择一个单元格并将它反转(反转表示 0 变 1 ,1 变 0 )。如果存在和它相邻的单元格,那么这些相邻的单元格也会被反转。(注:相邻的两个单元格共享同一条边。)
请你返回将矩阵 mat 转化为全零矩阵的最少反转次数,如果无法转化为全零矩阵,请返回 -1 。
二进制矩阵的每一个格子要么是 0 要么是 1 。
全零矩阵是所有格子都为 0 的矩阵。
示例 1:
输入:mat = [[0,0],[0,1]]
输出:3
解释:一个可能的解是反转 (1, 0),然后 (0, 1) ,最后是 (1, 1) 。
示例 2:
输入:mat = [[0]]
输出:0
解释:给出的矩阵是全零矩阵,所以你不需要改变它。
示例 3:
输入:mat = [[1,1,1],[1,0,1],[0,0,0]]
输出:6
示例 4:
输入:mat = [[1,0,0],[1,0,0]]
输出:-1
解释:该矩阵无法转变成全零矩阵
提示:
m == mat.length
n == mat[0].length
1 <= m <= 3
1 <= n <= 3
mat[i][j] 是 0 或 1 。
class Solution {
public:
typedef pair<int, int> pii;
int vis[1000], di, dj;
int rev(int rt, int pos) {
if (pos >= 0 && pos < di * dj) {
rt ^= (1 << pos);
}
return rt;
}
int flip(int rt, int pos) {
rt = rev(rt, pos);
if ((pos + 1) % dj != 0) rt = rev(rt, pos + 1);
if (pos % dj != 0) rt = rev(rt, pos - 1);
rt = rev(rt, pos + dj);
rt = rev(rt, pos - dj);
return rt;
}
int bfs(int s, int t) {
memset(vis, 0, sizeof(vis));
queue<pii> q;
q.push(make_pair(s, 0));
while (!q.empty()) {
pii u = q.front();
q.pop();
if (u.first == t) return u.second;
for (int j = 0; j < di * dj; j++) {
int to = flip(u.first, j);
if (vis[to]) continue;
q.push(make_pair(to, u.second + 1));
vis[to] = 1;
}
}
return -1;
}
int minFlips(vector<vector<int>> &mat) {
di = mat.size();
dj = mat[0].size();
int s = 0, t = 0;
for (int i = 0; i < di; i++) {
for (int j = 0; j < dj; j++) {
s <<= 1, s += mat[i][j];
}
}
return bfs(s, t);
}
};