【Warrior刷题笔记】1765.地图中的最高点 【多源广度优先遍历】详细注释简单易懂
作者:互联网
题目
解题思路
本题可以使用多源广度优先遍历解决。
题目要求得到高度值最大的高度安排方案,限制条件是相邻格子之间高度差最大为1
,同时水域的高度限定为了0
。因此我们可以从所有水域开始,与水域相邻的位置高度设置为1
,与高度为1
的位置相邻的格子高度设置为2
,以此类推,将所有未遍历过的相邻格子高度都设置为当前格子的高度值加一,这样既可以满足限制条件,也可以使地图中的最高点高度最大化。我们使用多源广度优先遍历算法解决:
- 计算数组长度
m
、宽度m
,初始化bfs
辅助队列q
,初始化存答案数组ans
所有值为-1
,ans
同时也充当哈希表标记每个格子是否已经遍历过了(即值是否为-1
); - 遍历一趟输入数组,将所有水域位置高度设置为
0
,并将其位置入队; - 只要队列非空,遍历队列中元素的四个相邻位置,将其中未曾遍历过的位置高度设置为当前位置的高度加一,并入队;
- 弹出当前位置;
- 当队列为空时,表示已遍历完毕,返回答案数组。
代码
class Solution {
public:
vector<vector<int>> highestPeak(vector<vector<int>>& isWater) {
int m = isWater.size();//输入数组长度
int n = isWater[0].size();//输入数组宽度
queue<pair<int,int>> q;//bfs辅助队列
vector<vector<int>> ans(m,vector<int>(n,-1));//存答案,同时充当哈希表标记当前为止是否遍历过
for(int i = 0; i < m; ++i){//将所有水域入队
for(int j = 0; j < n; ++j){
if(isWater[i][j]){
ans[i][j] = 0;//水域高度为0
q.emplace(make_pair(i,j));
}
}
}
const int direction[4][2] = {{-1,0},{1,0},{0,-1},{0,1}};//方向辅助数组
while(!q.empty()){//只要队列非空
auto& [i,j] = q.front();//得到当前位置坐标
for(const auto& d : direction){//遍历四个方向
if(i+d[0]<m && i+d[0]>=0 && j+d[1]<n && j+d[1]>=0 && ans[i+d[0]][j+d[1]]==-1){
ans[i+d[0]][j+d[1]] = ans[i][j] + 1;//将四个相邻方向上未遍历过的位置高度修改为当前位置高度+1
q.emplace(make_pair(i+d[0],j+d[1]));//同时将其入队
}
}
q.pop();//出队当前位置
}
return ans;//返回答案
}
};
复杂度分析
时间复杂度: O(m*n)
。m
为地图长度,n
为地图宽度。入队水域位置需要O(mn)
时间,广度优先遍历需要O(mn)
时间,总体时间复杂度O(mn)
。
空间复杂度: O(mn)
。存储答案的数组需要O(mn)
空间,辅助队列最大需要O(mn)
空间,总体空间复杂度O(mn)
。
标签:Warrior,遍历,数组,mn,高度,位置,ans,多源,刷题 来源: https://blog.csdn.net/qq_39255924/article/details/122741837