题目描述
你现在手里有一份大小为 N x N 的『地图』(网格) grid
,上面的每个『区域』(单元格)都用 0
和 1
标记好了。其中 0
代表海洋,1
代表陆地,你知道距离陆地区域最远的海洋区域是是哪一个吗?请返回该海洋区域到离它最近的陆地区域的距离。
我们这里说的距离是『曼哈顿距离』( Manhattan Distance):(x0, y0)
和 (x1, y1)
这两个区域之间的距离是 |x0 - x1| + |y0 - y1|
。
输入:[[1,0,1],[0,0,0],[1,0,1]]
输出:2
解释:
海洋区域 (1, 1) 和所有陆地区域之间的距离都达到最大,最大距离为 2。
解题思路
这种找距离的题目是典型的“广度优先搜索”题目。
思路:一看到最值,首先想到BFS。我们可以先找出所有的陆地,然后从陆地开始向外进行BFS式的扩散,然后每扩散一层就将计数器加一,不断“填海造陆”直到整个地图再也不存在海洋为止。这个时候的计数器就是最远的海洋距离陆地的距离。
参考代码
class Solution {
public:
int maxDistance(vector<vector<int>>& grid) {
int rows = grid.size();
if(rows == 0)
return 0;
int cols = grid[0].size();
int dx[] = {0, 0, 1, -1};
int dy[] = {1, -1, 0, 0};
queue<int> q;
for(int i = 0; i < rows; i++){
for(int j = 0; j < cols; j++){
if(grid[i][j] == 1)
q.push(i*cols + j); // 小技巧
}
}
if(q.size() == 0 || q.size() == rows * cols)
return -1;
int res = 0;
bool flag = false; // 设置这里flag的目的是防止计数多一个
while(!q.empty()){
int sizeOfq = q.size();
while(sizeOfq--){ // 这个while会保证遍历“一整圈”(自己理解)
int tmp = q.front();
q.pop();
int row = tmp / cols; // 小技巧,恢复坐标
int col = tmp % cols;
for(int i = 0; i < 4; i++){
int new_row = row + dx[i];
int new_col = col + dy[i];
if(new_row >= 0 && new_row < rows && new_col >= 0 && new_col < cols && grid[new_row][new_col] == 0){
grid[new_row][new_col] = 1; // bfs,必须在添加进queue的时候就进行着色,否则可能有重复遍历的问题!!
q.push(new_row * cols + new_col);
flag = true;
}
}
}
if(flag){
res++;
flag = false;
}
}
return res;
}
};