思路1: DFS,对于每个门进行一次DFS搜索,记录每个位置对每个门的距离,当有更小距离的门时更新这个数值
public void WallsAndGates(int[][] rooms) {
for (int i = 0; i < rooms.GetLength(0); i++)
{
for (int j = 0; j < rooms[i].GetLength(0); j++)
{
if (rooms[i][j] == 0)
{
DFS(rooms, i, j, 0);
}
}
}
}
void DFS(int[][] rooms, int x, int y, int val)
{
if (x < 0 || x >= rooms.GetLength(0))
return;
if (y < 0 || y >= rooms[x].GetLength(0))
return;
if (rooms[x][y] < val)
return;
rooms[x][y] = val;
DFS(rooms, x + 1, y, val + 1);
DFS(rooms, x, y + 1, val + 1);
DFS(rooms, x - 1, y, val + 1);
DFS(rooms, x, y - 1, val + 1);
}
思路2: 多源BFS,先把每个门都压入队列中,然后进行BFS搜索,BFS搜索保证了每个位置只需要遍历到一次,第一次搜索到时一定是最短距离,因此这种算法对于大量数据时肯定会更优秀
private List<int[]> directions = new List<int[]>(){new int[]{1, 0}, new int[]{-1, 0},new int[]{0, 1},new int[]{0, -1}};
private const int INF = 2147483647;
public void WallsAndGates(int[][] rooms)
{
Queue<int[]> queue = new Queue<int[]>();
int maxRow = rooms.GetLength(0);
if(maxRow == 0)
return;
int maxCow = rooms[0].Length;
for (int i = 0; i < maxRow; i++)
{
for (int j = 0; j < maxCow; j++)
{
if (rooms[i][j] == 0)
{
queue.Enqueue(new int[]{i,j});
}
}
}
while(queue.Count > 0)
{
int[] tile = queue.Dequeue();
for(int i = 0; i < directions.Count; i++)
{
int x = tile[0] + directions[i][0];
int y = tile[1] + directions[i][1];
if(x < 0 || x > maxRow - 1 || y < 0 || y > maxCow - 1 || rooms[x][y] != INF)
{
continue;
}
rooms[x][y] = rooms[tile[0]][tile[1]] + 1;
queue.Enqueue(new int[]{x, y});
}
}
}
}
判题的结果是两者时间差不多太多,都在340ms左右,但是明显在数据量大的情况下应该是多源BFS算法更优秀很多。多源BFS最快是328ms,第一次的704ms是因为用了List没有Queue