LeetCode 5282. 轉化為全零矩陣的最少反轉次數 bfs 雙向bfs
阿新 • • 發佈:2019-12-08
地址 https://leetcode-cn.com/submissions/detail/39277402/
題目描述
給你一個 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 直接使用二維陣列 而沒有進行壓縮變形
不過程式碼也比較好理解
程式碼如下:
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 };
&n