leetcode 1162.地图分析
题干
你现在手里有一份大小为 N x N 的 网格 grid,上面的每个 单元格 都用 0 和 1 标记好了。其中 0 代表海洋,1 代表陆地,请你找出一个海洋单元格,这个海洋单元格到离它最近的陆地单元格的距离是最大的。
我们这里说的距离是「曼哈顿距离」( Manhattan Distance):(x0, y0) 和 (x1, y1) 这两个单元格之间的距离是 |x0 - x1| + |y0 - y1| 。
如果网格上只有陆地或者海洋,请返回 -1。
示例 1:
输入:[[1,0,1],[0,0,0],[1,0,1]]
输出:2
海洋单元格 (1, 1) 和所有陆地单元格之间的距离都达到最大,最大距离为 2。
示例 2:
输入:[[1,0,0],[0,0,0],[0,0,0]]
输出:4
海洋单元格 (2, 2) 和所有陆地单元格之间的距离都达到最大,最大距离为 4。
提示:
1 <= grid.length == grid[0].length <= 100
grid[i][j] 不是 0 就是 1
题解
注意点:
* 代码效率很低…
* bfs使用queue时仍要设置vis数组,但是vis数组应当在bfs函数开头进行初始化,否则在不同的点进行bfs时就会导致不必要的去重
* 因为代码的效率已经很低了,所以将vis的判断放到了遍历邻格的处理中,这样一定程度上提高了效率
* 其实在Q.front()的时候可以使用auto来声明变量,这样可以减少一定的代码量
* 我的代码仍然没有找到好的方法处理整张地图全是海的情况
class Solution {
public:
int vis[105][105];
int ans = -1;
int N;
int dx[4] = { 0,0,-1,1 };
int dy[4] = { -1,1,0,0 };
bool check(int x, int y) {
if (x < 0 || x >= N || y < 0 || y >= N)
return false;
else
return true;
}
void bfs(vector<vector<int>>& grid, int x, int y) {
memset(vis,0,sizeof(vis));
queue<pair<int, int>> Q;
pair<int, int> start(x, y);
Q.push(start);
while (!Q.empty())
{
pair<int, int> now(Q.front());
//cout<<now.first<<' '<<now.second<<endl;
Q.pop();
if (grid[now.first][now.second] == 1)//当前格为陆地的情况
{
//cout<<'*'<<now.first<<' '<<now.second<<endl;
ans = max(ans, abs(now.first - x) + abs(now.second - y));
break;
}
//**else if(vis[now.first][now.second]==1)//当前格为海但已经访问过的情况**
//**continue;**
//**vis[now.first][now.second] = 1;**
for (int i = 0; i < 4; i++)
{
if (check(now.first + dx[i], now.second + dy[i])&&vis[now.first + dx[i]][now.second + dy[i]]==0)//若目标格不超界且未被访问过
{
pair<int, int> temp(now.first + dx[i], now.second + dy[i]);
Q.push(temp);
vis[now.first + dx[i]][now.second + dy[i]] = 1;
}
}
}
}
int maxDistance(vector<vector<int>>& grid) {
N = grid.size();
if (N == 0) return -1;
bool noLandFlag = true;
for (int i = 0; i < N; i++)
{
for (int j = 0; j < N; j++)
{
if (grid[i][j] == 1)
noLandFlag = false;
}
}
if(noLandFlag==true)
return -1;
for (int i = 0; i < N; i++)
{
for (int j = 0; j < N; j++)
{
if (grid[i][j] == 0)
bfs(grid, i, j);
}
}
return ans;
}
};
//从海洋点开始bfs,获得该点到最近陆地的距离,所有距离里取最大值
官方题解
好吧官方的题解效率并不比我的写法高
class Solution {
public:
static constexpr int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1};
static constexpr int MAX_N = 100 + 5;
struct Coordinate {
int x, y, step;
};
int n, m;
vector<vector<int>> a;
bool vis[MAX_N][MAX_N];
int findNearestLand(int x, int y) {
memset(vis, 0, sizeof vis);
queue <Coordinate> q;
q.push({x, y, 0});
vis[x][y] = 1;
while (!q.empty()) {
auto f = q.front(); q.pop();
for (int i = 0; i < 4; ++i) {
int nx = f.x + dx[i], ny = f.y + dy[i];
if (!(nx >= 0 && nx <= n - 1 && ny >= 0 && ny <= m - 1)) continue;
if (!vis[nx][ny]) {
q.push({nx, ny, f.step + 1});
vis[nx][ny] = 1;
if (a[nx][ny]) return f.step + 1;
}
}
}
return -1;
}
int maxDistance(vector<vector<int>>& grid) {
this->n = grid.size();
this->m = grid.at(0).size();
a = grid;
int ans = -1;
for (int i = 0; i < n; ++i) {
for (int j = 0; j < m; ++j) {
if (!a[i][j]) {
ans = max(ans, findNearestLand(i, j));
}
}
}
return ans;
}
};