# [LeetCode 542. 01 Matrix ]() ### Daily challenge Jul 29, 2021 (MEDIAN) >Given an `m x n` binary matrix `mat`, return the distance of the nearest `0` for each cell. > >The distance between two adjacent cells is `1`. ![](https://i.imgur.com/EyhNGlm.png) :::info **Example 1:** **Input:** mat = [[0,0,0],[0,1,0],[0,0,0]] **Output:** [[0,0,0],[0,1,0],[0,0,0]] ::: ![](https://i.imgur.com/SOxtsxb.png) :::info **Example 2:** **Input:** mat = [[0,0,0],[0,1,0],[1,1,1]] **Output:** [[0,0,0],[0,1,0],[1,2,1]] ::: :::warning **Constraints:** * m == mat.length * n == mat[i].length * 1 <= m, n <= 104 * 1 <= m * n <= 104 * mat[i][j] is either 0 or 1. * There is at least one 0 in mat. ::: --- ### Approach 1 : BFS :bulb: **`132 ms ( 22.09% )`** **`O()`** :::success 使用 `1` 去搜尋最近的 `0`。 速度較慢且浪費空間,出現很多的多餘計算 :x:。 ::: * 使用 `ans` 紀錄距離。 > 1. `mat[i][j] == 0`,距離為 0 ---> `ans[i][j] = 0`。 > 2. `mat[i][j] == 1` ---> 使用 **`BFS`** 尋找最近的 `0`。 * BFS : > 1. `dir` 紀錄走的方向、`used` 紀錄走過的位置、`step` 紀錄步數。 > 2. 判斷 `next_x`、`next_y`。 >> * 若不在 `mat` 範圍內 ---> 不必判斷。 >> * 若 **`mat[next_x][next_y] == 0`** ---> **找到答案**,並回傳 `step`。 >> * 若沒有走過 ---> `push` 到 `queue` 中,並記錄位置。 ```cpp=1 class Solution { public: int dir[4][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}}; int BFS(pair<int, int> one, vector<vector<int>>& mat){ int m = mat.size(); int n = mat[0].size(); bool used[m][n]; memset(used, false, sizeof(used)); queue<pair<int, int>> bfs; bfs.push(one); int step = 1; while(bfs.size() != 0){ for(int i=bfs.size()-1; i>=0; i--){ auto now = bfs.front(); bfs.pop(); for(auto DIR : dir){ int next_x = now.first + DIR[0]; int next_y = now.second + DIR[1]; if(next_x < 0 || next_x >= m || next_y < 0 || next_y >= n) continue; if(mat[next_x][next_y] == 0) return step; if(!used[next_x][next_y]){ used[next_x][next_y] = true; bfs.push({next_x, next_y}); } } } step++; } return -1; } vector<vector<int>> updateMatrix(vector<vector<int>>& mat) { int m = mat.size(); int n = mat[0].size(); vector<vector<int>> ans(m, vector<int>(n, 0)); for(int i=0; i < m; i++){ for(int j=0; j < n; j++){ if(mat[i][j] == 1) ans[i][j] = BFS({i, j}, mat); } } return ans; } }; ``` ### Approach 2 : BFS :book: **`68 ms ( 72.39% )`** **`O()`** :::success 使用 `0` 去搜尋附近的 `1` :o:。 整體與 `Approach 1` 想法相同。 ::: 與 `Approach 1` 不同的地方 : * 將 `mat[i][j] == 1` 的部分先設為 `INT_MAX`。 `mat[i][j] == 0` 的部分存入 `queue` 中。 * BFS : > 同樣判斷 `next_x`、`next_y`。 >> 1. `mat[next_x][next_y] == 0` ---> 不必判斷,因為只會增加步數。 >> 2. `mat[next_x][next_y] == 1` >> ---> 判斷當前 `ans[next_x][next_y]` 以及 `ans[x][y] + 1` 大小。 >> ---> 若 `ans[next_x][next_y] > ans[x][y] + 1`,表示從當前的`{ x, y }` 走到 >> `{ next_x, next_y }` 會有較近的距離。 >> ---> 若 `ans[next_x][next_y] <= ans[x][y] + 1`,則表示之前所記錄走到 >> `{ next_x, next_y }` 已經是較好的結果。 ```cpp=1 class Solution { public: int dir[4][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}}; vector<vector<int>> updateMatrix(vector<vector<int>>& mat) { int m = mat.size(); int n = mat[0].size(); queue<pair<int, int>> bfs; vector<vector<int>> ans(m, vector<int>(n, INT_MAX)); for(int i=0; i < m; i++){ for(int j=0; j < n; j++){ if(mat[i][j] == 0){ bfs.push({i, j}); ans[i][j] = 0; } } } while(!bfs.empty()){ for(int i=bfs.size()-1; i>=0; i--){ pair<int, int> now = bfs.front(); bfs.pop(); for(auto DIR : dir){ int next_x = now.first + DIR[0]; int next_y = now.second + DIR[1]; if(next_x < 0 || next_x >= m || next_y < 0 || next_y >= n || ans[next_x][next_y] <= ans[now.first][now.second] + 1) continue; bfs.push({next_x, next_y}); ans[next_x][next_y] = ans[now.first][now.second] + 1; } } } return ans; } }; ```