持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第24天,点击查看活动详情
题目描述
给你一个大小为 m x n 的整数矩阵 isWater ,它代表了一个由 陆地 和 水域 单元格组成的地图。
- 如果 isWater[i][j] == 0 ,格子 (i, j) 是一个 陆地 格子。
- 如果 isWater[i][j] == 1 ,格子 (i, j) 是一个 水域 格子。
你需要按照如下规则给每个单元格安排高度:
- 每个格子的高度都必须是非负的。
- 如果一个格子是 水域 ,那么它的高度必须为 0 。
- 任意相邻的格子高度差 至多 为 1 。当两个格子在正东、南、西、北方向上相互紧挨着,就称它们为相邻的格子。(也就是说它们有一条公共边)
找到一种安排高度的方案,使得矩阵中的最高高度值 最大 。
请你返回一个大小为 m x n 的整数矩阵 height ,其中 height[i][j] 是格子 (i, j) 的高度。如果有多种解法,请返回 任意一个 。
示例 1:
输入:isWater = [[0,1],[0,0]] 输出:[[1,0],[2,1]] 解释:上图展示了给各个格子安排的高度。 蓝色格子是水域格,绿色格子是陆地格。
BFS广度优先搜索
思路分析:首先我们看到这种题目,想都不用想肯定是用搜索的,不是bfs就是dfs就是看哪一种符合情况。本题就是bfs广度优先搜索。我的实现思路如下:
- 首先确定所有水域的位置,将其值赋位0,进行初始化。
- 在通过数组ans来构建访问矩阵,用于避免重复访问,初始水域的位置标记为已访问,防止超时。
- 再构建结果数组,用于存放最后的结果
- 构建一个队列queue来进行BFS搜索,进行入队出队的操作。直到队列为空停止搜索。
class Solution {
int[][] dirs = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
public int[][] highestPeak(int[][] isWater) {
int m = isWater.length, n = isWater[0].length;
int [][] ans = new int[m][n];
for (int i = 0 ; i < m ; i++){
Arrays.fill(ans[i],-1);
}
Queue<int []> queue = new ArrayDeque<>();
for (int i = 0 ; i < m ; i++){
for (int j = 0 ; j < n ;j++){
if (isWater[i][j] == 1){
ans[i][j] = 0;
queue.offer(new int[]{i,j});
}
}
}
while ( !queue.isEmpty() ){
int[]p = queue.poll();
for (int [] dir:dirs){
int x = p[0]+dir[0],y = p[1]+dir[1];
if (x >= 0 && x < m && y >= 0 &&y < n && ans[x][y] == -1 ){
ans[x][y] = ans[p[0]][p[1]]+1;
queue.offer(new int[]{x,y});
}
}
}
return ans;
}
}
最后
这道题目写完才发现,是多源BFS,还去学了多源BFS,源点全部入队然后病毒式扩散至整张图结束扩散。注意的是,在用队列时,shift会超时,建议多用一个队列来辅助操作。