其他分享
首页 > 其他分享> > 【Warrior刷题笔记】1765.地图中的最高点 【多源广度优先遍历】详细注释简单易懂

【Warrior刷题笔记】1765.地图中的最高点 【多源广度优先遍历】详细注释简单易懂

作者:互联网

题目

LC1765.地图中的最高点

解题思路

本题可以使用多源广度优先遍历解决。
题目要求得到高度值最大的高度安排方案,限制条件是相邻格子之间高度差最大为1,同时水域的高度限定为了0。因此我们可以从所有水域开始,与水域相邻的位置高度设置为1,与高度为1的位置相邻的格子高度设置为2,以此类推,将所有未遍历过的相邻格子高度都设置为当前格子的高度值加一,这样既可以满足限制条件,也可以使地图中的最高点高度最大化。我们使用多源广度优先遍历算法解决:

  1. 计算数组长度m、宽度m,初始化bfs辅助队列q,初始化存答案数组ans所有值为-1ans同时也充当哈希表标记每个格子是否已经遍历过了(即值是否为-1);
  2. 遍历一趟输入数组,将所有水域位置高度设置为0,并将其位置入队;
  3. 只要队列非空,遍历队列中元素的四个相邻位置,将其中未曾遍历过的位置高度设置为当前位置的高度加一,并入队;
  4. 弹出当前位置;
  5. 当队列为空时,表示已遍历完毕,返回答案数组。

代码

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