LeetCode 542. 01 Matrix
https://leetcode.com/problems/01-matrix/solution/
Given a matrix consists of 0 and 1, find the distance of the nearest 0 for each cell.
The distance between two adjacent cells is 1.Example 1:
Input:
0 0 0 0 1 0 0 0 0Output:
0 0 0 0 1 0 0 0 0
Example 2:
Input:
0 0 0 0 1 0 1 1 1Output:
0 0 0 0 1 0 1 2 1
Note:
- The number of elements of the given matrix will not exceed 10,000.
- There are at least one 0 in the given matrix.
- The cells are adjacent in only four directions: up, down, left and right.
方法1:BFS
Algorithm
- For our BFS routine, we keep a queue,
q
to maintain the queue of cells to be examined next. - We start by adding all the cells with
0
s toq
. - Intially, distance for each
0
cell is0
and distance for each1
isINT_MAX
, which is updated during the BFS. - Pop the cell from queue, and examine its neighbours. If the new calculated distance for neighbour
{i,j}
is smaller,
{i,j}
to
q
and update
dist[i][j]
.
vector<vector<int> > updateMatrix(vector<vector<int> >& matrix)
{
int rows = matrix.size();
if (rows == 0)
return matrix;
int cols = matrix[0].size();
vector<vector<int> > dist(rows, vector<int>(cols, INT_MAX));
queue<pair<int, int> > q;
for (int i = 0; i < rows; i++)
for (int j = 0; j < cols; j++)
if (matrix[i][j] == 0) {
dist[i][j] = 0;
q.push({ i, j }); //Put all 0s in the queue.
}
int dir[4][2] = { { -1, 0 }, { 1, 0 }, { 0, -1 }, { 0, 1 } };
while (!q.empty()) {
pair<int, int> curr = q.front();
q.pop();
for (int i = 0; i < 4; i++) {
int new_r = curr.first + dir[i][0], new_c = curr.second + dir[i][1];
if (new_r >= 0 && new_c >= 0 && new_r < rows && new_c < cols) {
if (dist[new_r][new_c] > dist[curr.first][curr.second] + 1) {
dist[new_r][new_c] = dist[curr.first][curr.second] + 1;
q.push({ new_r, new_c });
}
}
}
}
return dist;
}
方法2:DP 动态规划
Algorithm
- Iterate the matrix from top to bottom-left to right:
- Update {dist}[i][j]=min({dist}[i][j],min({dist}[i][j-1],{dist}[i-1][j])+1)
i.e., minimum of the current dist and distance from top or left neighbour +1,
that would have been already calculated previously in the current iteration.
- Now, we need to do the back iteration in the similar manner: from bottom to top-right to left:
- Update {dist}[i][j]=min({dist}[i][j],min({dist}[i][j+1],{dist}[i+1][j])+1)
i.e. minimum of current dist and distances calculated from bottom and right neighbours, that would be already
available in current iteration.
vector<vector<int> > updateMatrix(vector<vector<int> >& matrix)
{
int rows = matrix.size();
if (rows == 0)
return matrix;
int cols = matrix[0].size();
vector<vector<int> > dist(rows, vector<int>(cols, INT_MAX - 100000));
//First pass: check for left and top
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
if (matrix[i][j] == 0)
dist[i][j] = 0;
else {
if (i > 0)
dist[i][j] = min(dist[i][j], dist[i - 1][j] + 1);
if (j > 0)
dist[i][j] = min(dist[i][j], dist[i][j - 1] + 1);
}
}
}
//Second pass: check for bottom and right
for (int i = rows - 1; i >= 0; i--) {
for (int j = cols - 1; j >= 0; j--) {
if (i < rows - 1)
dist[i][j] = min(dist[i][j], dist[i + 1][j] + 1);
if (j < cols - 1)
dist[i][j] = min(dist[i][j], dist[i][j + 1] + 1);
}
}
return dist;
}