地图中的最高点
难度:
标签:
题目描述
给你一个大小为 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]] 解释:上图展示了给各个格子安排的高度。 蓝色格子是水域格,绿色格子是陆地格。
示例 2:
输入:isWater = [[0,0,1],[1,0,0],[0,0,0]] 输出:[[1,1,0],[0,1,1],[1,2,2]] 解释:所有安排方案中,最高可行高度为 2 。 任意安排方案中,只要最高高度为 2 且符合上述规则的,都为可行方案。
提示:
m == isWater.length
n == isWater[i].length
1 <= m, n <= 1000
isWater[i][j]
要么是0
,要么是1
。- 至少有 1 个水域格子。
代码结果
运行时间: 550 ms, 内存: 80.1 MB
/*
* 思路:
* 1. 使用Java Stream API,我们可以简化输入矩阵的处理。
* 2. 我们仍然使用广度优先搜索(BFS)来确定每个格子的高度。
* 3. 使用Stream API初始化队列和高度矩阵。
*/
import java.util.*;
import java.util.stream.*;
public class Solution {
public int[][] highestPeak(int[][] isWater) {
int m = isWater.length;
int n = isWater[0].length;
int[][] height = new int[m][n];
boolean[][] visited = new boolean[m][n];
Queue<int[]> queue = new LinkedList<>();
// 使用Stream API初始化队列和已访问矩阵
IntStream.range(0, m).forEach(i ->
IntStream.range(0, n).forEach(j -> {
if (isWater[i][j] == 1) {
queue.add(new int[]{i, j});
visited[i][j] = true;
}
})
);
// 四个方向的偏移量
int[][] directions = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
// 开始BFS
while (!queue.isEmpty()) {
int[] cell = queue.poll();
int x = cell[0];
int y = cell[1];
for (int[] d : directions) {
int nx = x + d[0];
int ny = y + d[1];
if (nx >= 0 && ny >= 0 && nx < m && ny < n && !visited[nx][ny]) {
height[nx][ny] = height[x][y] + 1;
queue.add(new int[]{nx, ny});
visited[nx][ny] = true;
}
}
}
return height;
}
}
解释
方法:
本题使用宽度优先搜索(BFS)的方式从每个水域(高度为0的单元格)开始向外扩展,为陆地单元格设置高度。我们使用一个队列来实现BFS,并在过程中记录每个单元格的高度。我们首先初始化所有水域单元格的高度为0并将它们加入队列。接着,对于队列中的每个元素,我们检查它的四个邻居单元格(上下左右)。如果某个邻居单元格的高度尚未被设置(即初始化的-1值),我们将其高度设置为当前单元格的高度加一,并将该邻居单元格加入队列中继续处理。这种方式保证了相邻单元格的高度差不会超过1,并且从水源开始最远的陆地单元格会获得最大的高度值。
时间复杂度:
O(m * n)
空间复杂度:
O(m * n)
代码细节讲解
🦆
在初始化高度矩阵时,为什么选择使用-1作为未设定高度的标志?是否有更直观的方式表示未设定的高度?
▷🦆
在BFS实现中,队列中的元素包括坐标和当前高度。请问这里的高度信息是否真的必要,考虑到高度可以从heights矩阵中直接获取?
▷🦆
算法检查每个单元格的四个邻居时,是否有重复检查的可能?如果有,这会对性能有什么影响?
▷🦆
您提到最坏情况下每个单元格都会被访问一次,但在何种情况下会发生所有单元格都需要被访问?
▷