leetcode 1284. 转化为全零矩阵的最少反转次数

给你一个 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);
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值