Problem
Given an N x N grid containing only values 0 and 1, where 0 represents water and 1 represents land, find a water cell such that its distance to the nearest land cell is maximized and return the distance.
The distance used in this problem is the Manhattan distance: the distance between two cells (x0, y0) and (x1, y1) is |x0 - x1| + |y0 - y1|.
If no land or water exists in the grid, return -1.
Example 1:
Input: [[1,0,1],[0,0,0],[1,0,1]]
Output: 2
Explanation:
The cell (1, 1) is as far as possible from all the land with distance 2.
Example 2:
Input: [[1,0,0],[0,0,0],[0,0,0]]
Output: 4
Explanation:
The cell (2, 2) is as far as possible from all the land with distance 4.
hui
Note:
- 1 <= grid.length == grid[0].length <= 100
- grid[i][j] is 0 or 1
解题思路
这一题的基本思路是使用BFS来进行搜索,可以从两个角度出发,我们可以从0的角度去找,也可以从1的角度去找。
第一种方法需要我们遍历所有的0的位置,在每一个位置处进行BFS,然后遇到1即可返回。很明显,这一种方法会做较多的重复操作。
第二张方法可以采用从所有的1位置同时出发的策略,一层层向外扩展,一直到所有的位置都已经被扫描到,这个时候即可返回层数,则表示所求的距离。
代码如下:
class Solution {
public:
int maxDistance(vector<vector<int>>& grid) {
vector<vector<int>> direction;
direction.push_back({ -1, 0 });
direction.push_back({ 1, 0 });
direction.push_back({ 0, -1 });
direction.push_back({ 0, 1 });
const int rows = grid.size();
const int cols = grid[0].size();
queue<pair<int, int>> q;
for (size_t i = 0; i < grid.size(); ++i)
{
for (size_t j = 0; j < grid[0].size(); ++j)
{
if (grid[i][j] == 1)
{
q.push(make_pair(i, j));
}
}
}
if (q.size() == 0 || q.size() == rows * cols)
{
return -1;
}
int length = 0;
while (!q.empty())
{
size_t len = q.size();
for (auto loop = 0; loop < len; ++loop)
{
auto node = q.front();
q.pop();
if (grid[node.first][node.second] == -1)
{
continue;
}
grid[node.first][node.second] = -1;
for (auto& direct : direction)
{
if (0 <= node.first + direct[0] && node.first + direct[0] < rows &&
0 <= node.second + direct[1] && node.second + direct[1] < cols)
{
q.push(make_pair(node.first + direct[0], node.second + direct[1]));
}
}
}
length += 1;
}
return length - 2;
}
};