给你一个 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 。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/minimum-number-of-flips-to-convert-binary-matrix-to-zero-matrix
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路
这种转化求最短的一眼bfs,(其实矩阵只有3x3,说不定dfs也可以,但是有bfs就不用dfs了)
用矩阵存储状态,那么我们每次要传递的状态是矩阵,这没什么,主要是剪枝不太好办,如果在不同层遇到同一矩阵,如何判断它在前面的层出现过?
这里将矩阵转为字符串,然后通过维护一张哈希set来记录已经出现过的矩阵(其实就是自己懒得写矩阵的哈希函数 )
那么状态有了,状态之间的转移也可以通过穷举位置来实现,那就直接bfs,然后如果搜到全0的矩阵,直接返回就是了
class Solution {
public:
// 将字符串Mat表示的矩阵的x,y坐标及其周边反转
void revs(string &Mat, int x, int y, int m, int n)
{
vector<string> mat(m);
for(int i=0; i<m; i++)
mat[i]=string(Mat.begin()+i*n