题目描述
给你一个 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 。
算法1
本题同acwing 95. 费解的开关 acwing116. 飞行员兄弟 类似
可以考虑第一层如何全零的时候 需要按那几个开关 第二层为如何全零的时候需要按那几个开关 依次推到至最后一层得到答案
在数据范围比较大的情况也可以采用 双向BFS 进行搜索范围的优化
由于范围比较小 我就采取了比较粗暴的朴素BFS
从全零的状态作为起点 依次BFS 看看走到题目给出的状态 需要几步
简单直接
用来做记录状态的key 直接使用二维数组 而没有进行压缩变形
不过代码也比较好理解
代码如下:
C++ 代码
class Solution {
public:
map<vector<vector<int>>, int> visit;
queue<pair<vector<vector<int>>, int>> q;
bool CheckIsAllZero(const vector<vector<int>> &mat)
{
for (int i = 0; i < mat.size(); i++) {
for (int j = 0; j < mat[0].size(); j++) {
if (mat[i][j] != 0)
return false;
}
}
return true;
}
void Click(vector<vector<int>>& currenrState, int x, int y)
{
int addx[4] = { 1,-1,0,0 };
int addy[4] = { 0,0,-1,1 };
currenrState[x][y] = currenrState[x][y] ? 0: 1;
for (int i = 0; i < 4; i++) {
int newx = x + addx[i];
int newy = y + addy[i];
if (newx >= 0 && newx < currenrState.size() && newy >= 0 && newy < currenrState[0].size()) {
currenrState[newx][newy] = currenrState[newx][newy] ? 0 : 1;
}
}
}
int minFlips(vector<vector<int>>& mat) {
if (CheckIsAllZero(mat)) return 0;
vector<vector<int>> matAllZero(mat.size(), vector<int>(mat[0].size()));
int distance = 0;
visit[matAllZero] = distance;
q.push({ matAllZero ,distance });
while (!q.empty()) {
auto qe = q.front();
q.pop();
vector<vector<int>> currenrState = qe.first;
int currentCount = qe.second;
//尝试 点击该XY
for (int i = 0; i < currenrState.size(); i++) {
for (int j = 0; j < currenrState[0].size(); j++) {
vector<vector<int>> copy = currenrState;
Click(copy, i, j);
if (copy == mat)
{
return currentCount + 1;
}
if (visit.count(copy) == 0) {
q.push({ copy ,currentCount + 1 });
visit[copy] = currentCount + 1;
}
}
}
}
return -1;
}
};