You are given a m x n 2D grid initialized with these three possible values.
-1
- A wall or an obstacle.0
- A gate.INF
- Infinity means an empty room. We use the value231 - 1 = 2147483647
to representINF
as you may assume that the distance to a gate is less than2147483647
.
Fill each empty room with the distance to its nearest gate. If it is impossible to reach a gate, it should be filled with INF
.
For example, given the 2D grid:
INF -1 0 INF INF INF INF -1 INF -1 INF -1 0 -1 INF INF
After running your function, the 2D grid should be:
3 -1 0 1 2 2 1 -1 1 -1 2 -1 0 -1 3 4
This method is not good but it is very straightforward.
#include <climits>
#include <vector>
#include <iostream>
using namespace std;
void wallsAndGates(vector< vector<int> >& matrix, int i, int j, vector< vector<bool> >& used, long long int& distance, long long int& minDis) {
if((i < 0) || (i == matrix.size()) || (j < 0) || (j == matrix[i].size())) {
return;
} else {
if(matrix[i][j] == 0) {
minDis = min(minDis, distance);
return;
}
}
vector< vector<int> > direction {
{0, 1},
{0, -1},
{-1, 0},
{1, 0}};
for(int k = 0; k < 4; ++k) {
int next_i = i + direction[k][0];
int next_j = j + direction[k][1];
if(next_i >= 0 && next_i < matrix.size() && next_j >= 0 && next_j < matrix[i].size() && (matrix[next_i][next_j] != -1) && (used[next_i][next_j] == false)) {
distance += 1;
used[next_i][next_j] = true;
wallsAndGates(matrix, next_i, next_j, used, distance, minDis);
distance -= 1;
used[next_i][next_j] = false;
}
}
}
void wallsAndGates(vector< vector<int> >& matrix) {
if(matrix.size() == 0 || matrix[0].size() == 0) return;
vector< vector<bool> > used(matrix.size(), vector<bool>(matrix[0].size(), false));
for(int i = 0; i < matrix.size(); ++i) {
for(int j = 0; j < matrix[i].size(); ++j) {
if((matrix[i][j] == INT_MAX) && (used[i][j] == false)) {
used[i][j] = true;
long long int distance = 0;
long long int minDistance = INT_MAX;
wallsAndGates(matrix, i, j, used, distance, minDistance);
used[i][j] = false;
matrix[i][j] = minDistance;
}
}
}
}
DFS can make it go much faster!
Think that, we actually dont need to get all the minDistance. All the INT_MAX surrounds '0' will have all dep == 1. Thus, we can use dfs to get all the room distance to one gate. Suppose we have two gates, the other gate distance needs to be changed only if the current distance is smaller than the other one.
void dfs(vector< vector<int> >& matrix, int i, int j, int dep) {
if(i < 0 || i >= matrix.size() || j < 0 || j >= matrix[i].size() || matrix[i][j] < dep) {
return;
}
matrix[i][j] = dep;
dfs(matrix, i + 1, j, dep + 1);
dfs(matrix, i - 1, j, dep + 1);
dfs(matrix, i, j + 1, dep + 1);
dfs(matrix, i, j - 1, dep + 1);
}
void wallsAndGatesII(vector< vector<int> >& matrix) {
for(int i = 0; i < matrix.size(); ++i) {
for(int j = 0; j < matrix[i].size(); ++j) {
if(matrix[i][j] == 0) {
dfs(matrix, i, j, 0);
}
}
}
}