📖本篇内容:leetcode每日一题1765. 地图中的最高点 简单的多源BFS最短路问题 模板题
📑 文章专栏:leetcode每日一题《打卡日常》
📆 最近更新:2022年1月28日 leetcode每日一题1996. 游戏中弱角色的数量 排序+遍历 实则是对lambda表达式的复习同时也是对贪心的复习
🙊个人简介:一只二本院校在读的大三程序猿,本着注重基础,打卡算法,分享技术作为个人的经验总结性的博文博主,虽然可能有时会犯懒,但是还是会坚持下去的,如果你很喜欢博文的话,建议看下面一行~(疯狂暗示QwQ)
🌇 点赞 👍 收藏 ⭐留言 📝 一键三连 关爱程序猿,从你我做起
🙊写在前面🙊
今天的题是典型的图论BFS,说白了就是一个简单的模板题,套模板就好啦~剩下的就是根据问题逻辑增加部分的逻辑基础即可!
题目
给你一个大小为
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 个水域格子。
📝思路📝
本题考察点:
单源BFS
:通常使用BFS求二者最短路,针对于一下的场景:从指定的起点
出发,求解到达特定终点
的最短距离。
这是一类特殊的「单源最短路」问题:本质是在一个边权为 1 的图上,求从特定「源点」出发到达特定「汇点」的最短路径。
求解本题时:转而言之就是我们需要对每个海洋节点源进行BFS
,找到每个海洋源点 最近的陆地距离的高度进行增加+1
,然后下一层次的陆地高度依据上一层高度增加+1。
多源BFS
:与单源最短路
不同,多源最短路的问题是从多个源点
到达一个/多个汇点
的最短路径。
就相比于我们找到陆地然后,求解陆地距离海洋的层次距离即可~
根据三叶姐的思路一起来写题哦~
⭐代码实现⭐
class Solution {
public int[][] highestPeak(int[][] isWater) {
int m = isWater.length;
int n = isWater[0].length;
//定义高度结果
int [][]height = new int[m][n];
//这里进行了初始化 每个海洋高度初始为-1,再次便利时会将高度+1
for (int i = 0 ; i< m;i++){
Arrays.fill(height[i],-1);
}
int dx[] = new int []{0,0,-1,1};//定义了扩散方向为下上左右的横坐标
int dy[] = new int []{-1,1,0,0};//定义了扩散方向为下上左右的纵坐标
//创建队列判断其是否入队
Queue<int[]> queue = new ArrayDeque<>();
for (int i = 0 ; i< m ;i++){
for (int j = 0 ; j< n ;j++){
//如果当前是陆地则默认高度为0,且将坐标入队
if (isWater[i][j] == 1){
height[i][j] = 0;
queue.add(new int[]{i,j});
}
}
}
//模板套题
while (!queue.isEmpty()){
//取出陆地的坐标
int point[] = queue.poll();
int x = point[0],y = point[1];
//依次向下上左右进行扩散
for (int i = 0 ; i< 4;i++){
//扩散后的坐标
int newX = x + dx[i];
int newY = y + dy[i];
//如果当前坐标越界或者不是默认值 也就说明遍历过的坐标
if (newX<0||newX>=m||newY<0||newY>=n || height[newX][newY] != -1){
continue;
}
//此时坐标的高度增加
height[newX][newY] = height[x][y] + 1;
//并且入队
queue.offer(new int[]{newX,newY});
}
}
//返回高度数组即可即可显示全部的坐标差
return height;
}
}
运行结果
🙊写在最后🙊
2022-1-29 今天小付打卡了哦~
美好的日出 美好的山河
都因有你存在 而璀璨 耀眼