leetcode 力扣每日一题系列详解——接雨水II 2021.11.3

本文详细解析了LeetCode上的接雨水II题目,通过广度优先搜索算法实现,介绍如何计算二维高度图最多能接多少雨水。从算法思路到代码实现均有详尽说明。

这是总目录leetcode 力扣每日一题系列详解——总目录


💡题目要求

  1. 接雨水 II
    给你一个 m x n 的矩阵,其中的值均为非负整数,代表二维高度图每个单元的高度,请计算图中形状最多能接多少体积的雨水。

示例 1:

输入: heightMap = [[1,4,3,1,3,2],[3,2,1,3,2,4],[2,3,3,2,3,1]]
输出: 4
解释: 下雨后,雨水将会被上图蓝色的方块中。总的接雨水量为1+2+1=4。
示例 2:

输入: heightMap = [[3,3,3,3,3],[3,2,2,2,3],[3,2,1,2,3],[3,2,2,2,3],[3,3,3,3,3]]
输出: 10

提示:

m == heightMap.length
n == heightMap[i].length
1 <= m, n <= 200
0 <= heightMap[i][j] <= 2 * 104

在这里插入图片描述


💡答案和解题思路

这个题我一开始的思路是能盛水的位置肯定不是最外圈,然后维护一个最高的围栏,然后再计算里面 盛水的面积,具体操作发现行不通,我就看了题解,然后整理下题解的思路,自己写了下,注释也都写的很清楚

🌲1.上代码

//广度优先搜索算法
    public int TrapRainWater(int[][] heightMap)
    {
        int result =0;
        int m = heightMap.Length;
        int n = heightMap[0].Length;
        int[] dirs = {-1,0,1,0,-1};
        //矩阵的最高高度
        int maxHeight = 0;
        for (int i = 0; i < m; i++)
        {
            for (int j = 0; j < n; j++)
            {
                maxHeight = Math.Max(maxHeight, heightMap[i][j]);
            }
        }
        //假设矩阵灌满了水
        int[,] water=new int[m,n];
        for (int i = 0; i < m; i++)
        {
            for (int j = 0; j < n; j++)
            {
                water[i, j] = maxHeight;
            }
        }
        //声明堆,先进先出
        Queue<int[]> qu=new Queue<int[]>();
        for (int i = 0; i < m; i++)
        {
            //筛选处最外圈的
            for (int j = 0; j < n; j++)
            {
                if (i==0||i==m-1||j==0||j==n-1)
                {
                    if (water[i,j]>heightMap[i][j])
                    {
                        //如果假设有水的高度大于实际高度,肯定水会流走,所以实际水的高度等于物体的实际高度
                        water[i, j] = heightMap[i][j];
                        //入堆
                        qu.Enqueue(new int[]{i,j});
                    }
                }
            }
        }

        while (qu.Count>0)
        {
            int[] current = qu.Dequeue();
            int x = current[0];
            int y = current[1];
            for (int i = 0; i < 4; i++)
            {
                int nx = x + dirs[i];
                int ny = y + dirs[i + 1];
                if (nx<0||nx>=m||ny<0||ny>=n)
                {
                    continue;
                }
                //当前格子有水的高度低于周围4个格子有水的高度,并且周围4个格子有水的高度分别大于自己原有的高度
                if (water[x,y]<water[nx,ny]&&water[nx,ny]>heightMap[nx][ny])
                {
                    //4周格子有水的高度就在当前格子有水的高度和原来自身的高度当中选一个最大的
                    water[nx, ny] = Math.Max(water[x, y], heightMap[nx][ny]);
                    //入堆
                    qu.Enqueue(new int[]{nx,ny});
                }
            }
        }
        //统计最后有水的数量
        for (int i = 0; i < m; i++)
        {
            for (int j = 0; j < n; j++)
            {
                result += water[i, j] - heightMap[i][j];
            }
        }

        return result;


    }

🌲2.解题思路

🏺1.假设给的矩阵全都装满水,水的高度等于矩阵的最高的高度
🏺2.最外圈,如果每个柱子的实际高度小于假设的装水的高度,那水就会流失,然后更新当前柱子实际装完水的高度。然后把流失水的几个柱子 入堆 存起来
🏺3.堆里的依次出堆,按照先进先出的原则,如果当前出堆的这个柱子前后左右的柱子有水高度并且前后左右的柱子有水的高度都大于实际高度,那他们的有水的实际高度就要在出堆柱子的有水高度和自己的实际高度中选一个最大的,然后 满足条件周围的柱子就 入堆,这样下去,最后在堆里面的,就是最后最高的那一道围栏。
🏺4.最后统计下水的量,每个柱子的水量=有水的高度-柱子实际的高度。

💡二、知识点学习

今天的知识点就是:广度优先搜索
堆的先进先出
维护的这个堆永远都是最高的那一圈围栏


总结

欢迎大佬多多来给萌新指正,欢迎大家来共同探讨。
如果各位看官觉得文章有点点帮助,跪求各位给点个“一键三连”,谢啦~

声明:本博文章若非特殊注明皆为原创原文链接
https://blog.youkuaiyun.com/Wrinkle2017/article/details/121121607
————————————————————————————————

💢💢版权声明

版权声明:本博客为非营利性个人原创
所刊登的所有作品的著作权均为本人所拥有
本人保留所有法定权利,违者必究!
对于需要复制、转载、链接和传播博客文章或内容的
请及时和本博主进行联系
对于经本博主明确授权和许可使用文章及内容的
使用时请注明文章或内容出处并注明网址
转载请附上原文出处链接及本声明

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值