zoukankan      html  css  js  c++  java
  • LeetCode 1284. 转化为全零矩阵的最少反转次数 bfs 双向bfs

    地址  https://leetcode-cn.com/problems/minimum-number-of-flips-to-convert-binary-matrix-to-zero-matrix/

    题目描述
    给你一个 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] 是 01

    算法1
    本题同acwing 95. 费解的开关 acwing116. 飞行员兄弟 类似

    可以考虑第一层如何全零的时候 需要按那几个开关 第二层为如何全零的时候需要按那几个开关 依次推到至最后一层得到答案

    在数据范围比较大的情况也可以采用 双向BFS 进行搜索范围的优化

    由于范围比较小 我就采取了比较粗暴的朴素BFS
    从全零的状态作为起点 依次BFS 看看走到题目给出的状态 需要几步
    简单直接
    用来做记录状态的key 直接使用二维数组 而没有进行压缩变形
    不过代码也比较好理解
    代码如下:

     1 class Solution {
     2 public:
     3 
     4 map<vector<vector<int>>, int> visit;
     5 queue<pair<vector<vector<int>>, int>> q;
     6 bool CheckIsAllZero(const vector<vector<int>> &mat)
     7 {
     8     for (int i = 0; i < mat.size(); i++) {
     9         for (int j = 0; j < mat[0].size(); j++) {
    10             if (mat[i][j] != 0)
    11                 return false;
    12         }
    13     }
    14 
    15     return true;
    16 }
    17 
    18 
    19 void Click(vector<vector<int>>& currenrState, int x, int y)
    20 {
    21     int addx[4] = { 1,-1,0,0 };
    22     int addy[4] = { 0,0,-1,1 };
    23 
    24     currenrState[x][y] = currenrState[x][y] ? 0: 1;
    25 
    26     for (int i = 0; i < 4; i++) {
    27         int newx = x + addx[i];
    28         int newy = y + addy[i];
    29 
    30         if (newx >= 0 && newx < currenrState.size() && newy >= 0 && newy < currenrState[0].size()) {
    31             currenrState[newx][newy] = currenrState[newx][newy] ? 0 : 1;
    32         }
    33     }
    34 }
    35 
    36 
    37 int minFlips(vector<vector<int>>& mat) {
    38     if (CheckIsAllZero(mat)) return 0;
    39 
    40     vector<vector<int>> matAllZero(mat.size(), vector<int>(mat[0].size()));
    41 
    42     int distance = 0;
    43 
    44     visit[matAllZero] = distance;
    45     q.push({ matAllZero ,distance });
    46 
    47     while (!q.empty()) {
    48         auto qe = q.front();
    49         q.pop();
    50         vector<vector<int>> currenrState = qe.first;
    51         int currentCount = qe.second;
    52 
    53         //尝试 点击该XY
    54         for (int i = 0; i < currenrState.size(); i++) {
    55             for (int j = 0; j < currenrState[0].size(); j++) {
    56                 vector<vector<int>> copy = currenrState;
    57                 Click(copy, i, j);
    58 
    59 
    60                 if (copy == mat)
    61                 {
    62                     return currentCount + 1;
    63                 }
    64 
    65                 if (visit.count(copy) == 0) {
    66                     q.push({ copy ,currentCount + 1 });
    67                     visit[copy] = currentCount + 1;
    68                 }
    69             }
    70         }
    71     }
    72 
    73 
    74     return -1;
    75 }
    76 
    77 };
    View Code
    作 者: itdef
    欢迎转帖 请保持文本完整并注明出处
    技术博客 http://www.cnblogs.com/itdef/
    B站算法视频题解
    https://space.bilibili.com/18508846
    qq 151435887
    gitee https://gitee.com/def/
    欢迎c c++ 算法爱好者 windows驱动爱好者 服务器程序员沟通交流
    如果觉得不错,欢迎点赞,你的鼓励就是我的动力
    阿里打赏 微信打赏
  • 相关阅读:
    poj1466
    vc剪贴板
    【转帖】BCGControlBar使用心得如何捕获Workspace bar类上的树控件的消息
    Windows API一日一练
    BCG 使用CBCGPToolbarFontSizeCombo 时下拉框无内容
    VB API教程 王国荣
    用API 现成的函数处理工程退出时的文件保存
    VC 剪贴板操作
    BCG中使用状态栏显示状态信息
    界面库
  • 原文地址:https://www.cnblogs.com/itdef/p/12005600.html
Copyright © 2011-2022 走看看