LeetCode 407. Trapping Rain Water II

博客转载自:http://www.cnblogs.com/grandyang/p/5928987.html
【太难了,被智商碾压。。。。】
这道题是之前那道Trapping Rain Water的拓展,由2D变3D了,感觉很叼。但其实解法跟之前的完全不同了,之前那道题由于是二维的,我们可以用双指针来做,而这道三维的,我们需要用BFS来做,解法思路很巧妙,下面我们就以题目中的例子来进行分析讲解,多图预警,手机流量党慎入:
首先我们应该能分析出,能装水的底面肯定不能在边界上,因为边界上的点无法封闭,那么所有边界上的点都可以加入queue,当作BFS的启动点,同时我们需要一个二维数组来标记访问过的点,访问过的点我们用红色来表示,那么如下图所示:

我们再想想,怎么样可以成功的装进去水呢,是不是周围的高度都应该比当前的高度高,形成一个凹槽才能装水,而且装水量取决于周围最小的那个高度,有点像木桶原理的感觉,那么为了模拟这种方法,我们采用模拟海平面上升的方法来做,我们维护一个海平面高度mx,初始化为最小值,从1开始往上升,那么我们BFS遍历的时候就需要从高度最小的格子开始遍历,那么我们的queue就不能使用普通队列了,而是使用优先级队列,将高度小的放在队首,最先取出,这样我们就可以遍历高度为1的三个格子,用绿色标记出来了,如下图所示:

如上图所示,向周围BFS搜索的条件是不能越界,且周围格子未被访问,那么可以看出上面的第一个和最后一个绿格子无法进一步搜索,只有第一行中间那个绿格子可以搜索,其周围有一个灰格子未被访问过,将其加入优先队列queue中,然后标记为红色,如下图所示:

那么优先队列queue中高度为1的格子遍历完了,此时海平面上升1,变为2,此时我们遍历优先队列queue中高度为2的格子,有3个,如下图绿色标记所示:

我们发现这三个绿格子周围的格子均已被访问过了,所以不做任何操作,海平面继续上升,变为4,遍历所有高度为4的格子,如下图绿色标记所示:

由于我们没有特别声明高度相同的格子在优先队列queue中的顺序,所以应该是随机的,其实谁先遍历到都一样,对结果没啥影响,我们就假设第一行的两个绿格子先遍历到,那么那么周围各有一个灰格子可以遍历,这两个灰格子比海平面低了,可以存水了,把存水量算出来加入结果res中,如下图所示:

上图中这两个遍历到的蓝格子会被加入优先队列queue中,由于它们的高度小,所以下一次从优先队列queue中取格子时,它们会被优先遍历到,那么左边的那个蓝格子进行BFS搜索,就会遍历到其左边的那个灰格子,由于其高度小于海平面,也可以存水,将存水量算出来加入结果res中,如下图所示:

等两个绿格子遍历结束了,它们会被标记为红色,蓝格子遍历会先被标记红色,然后加入优先队列queue中,由于其周围格子全变成红色了,所有不会有任何操作,如下图所示:

此时所有的格子都标记为红色了,海平面继续上升,继续遍历完优先队列queue中的格子,不过已经不会对结果有任何影响了,因为所有的格子都已经访问过了,此时等循环结束后返回res即可,参见代码如下:

class Solution {
public:int trapRainWater(vector<vector<int>>& heightMap) {if (heightMap.empty()) return 0;int m = heightMap.size(), n = heightMap[0].size(), res = 0, mx = INT_MIN;priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> q;vector<vector<bool>> visited(m, vector<bool>(n, false));vector<vector<int>> dir{{0,-1},{-1,0},{0,1},{1,0}};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) {q.push({heightMap[i][j], i * n + j});visited[i][j] = true;}}}while (!q.empty()) {auto t = q.top(); q.pop();int h = t.first, r = t.second / n, c = t.second % n;mx = max(mx, h);for (int i = 0; i < dir.size(); ++i) {int x = r + dir[i][0], y = c + dir[i][1];if (x < 0 || x >= m || y < 0 || y >= n || visited[x][y]) continue;visited[x][y] = true;if (heightMap[x][y] < mx) res += mx - heightMap[x][y];q.push({heightMap[x][y], x * n + y});}}return res;}
};

【重点:BFS】LeetCode 407. Trapping Rain Water II相关推荐

  1. Leetcode 407. Trapping Rain Water II 收集雨水2 解题报告

    1 解题思想 我看了下题目,发现比预想中的简单,加之我比较烂,所以其实我还是没做,只是看懂了上回贴的代码,然后做了一下注释,现在我来讲下题目. 首先请看下上一题,上一题是2D的这题是3D的: Leet ...

  2. 【重点:DP 双指针 栈】LeetCode 42. Trapping Rain Water

    LeetCode 42. Trapping Rain Water 本博客转载自:http://www.cnblogs.com/grandyang/p/4402392.html [自己又不会做,抄的-& ...

  3. leetcode#42 Trapping rain water的五种解法详解

    leetcode#42 Trapping rain water 这道题十分有意思,可以用很多方法做出来,每种方法的思想都值得让人细细体会. 42. Trapping Rain Water Given ...

  4. LeetCode 42. Trapping Rain Water 【两种解法】(python排序遍历,C++ STL map存索引,时间复杂度O(nlogn))

    LeetCode 42. Trapping Rain Water Python解法 解题思路: 本思路需找到最高点左右遍历,时间复杂度O(nlogn),以下为向左遍历的过程. 将每一个点的高度和索引存 ...

  5. LeetCode 42 Trapping Rain Water 收集雨水

    LeetCode 42 Trapping Rain Water 收集雨水 Given n non-negative integers representing an elevation map whe ...

  6. Leetcode 动态规划 Trapping Rain Water

    本文为senlie原创.转载请保留此地址:http://blog.csdn.net/zhengsenlie Trapping Rain Water Total Accepted: 14568 Tota ...

  7. LeetCode 42. Trapping Rain Water(收集雨水Ⅰ)

    题目描述: Given n non-negative integers representing an elevation map where the width of each bar is 1, ...

  8. Java for LeetCode 042 Trapping Rain Water

    Given n non-negative integers representing an elevation map where the width of each bar is 1, comput ...

  9. [LeetCode]42. Trapping Rain Water雨水填坑

    这个题难点在于无法保证右边是不是有更高的墙可以保证挡住水 双指针可以解决 /*两边指针保证,保证另外一边肯定有能挡住水的地方.如果从一边开始,不考虑另一边,是无法保证右边肯定有挡水的墙,如果右边只都比 ...

最新文章

  1. Ubuntu下配置Nginx HTTPS
  2. 拼多多回应开除程序员:严重违反员工行为规范,因此解约!
  3. python中对数组合并的方法
  4. java并发编程之美-阅读记录1
  5. 【算法分析与设计】实验 分治算法解决中位数问题
  6. DevOps组织如何选取拓扑结构以提升协作效能
  7. 微商人赚钱的4个落地动作
  8. 你用什么型号手机呢?体验如何?
  9. DB2 char()函数引起全表扫描
  10. mysql5.7安装教程centos_CentOS7下MySQL5.7安装配置方法图文教程(YUM)
  11. mysql建表的字段类型和约束条件
  12. (CVPR2019)图像语义分割(18) DANet-集成双路注意力机制的场景分割网络
  13. BZOJ 1606: [Usaco2008 Dec]Hay For Sale 购买干草
  14. 老旧电脑救星,Windows 8.1 原始系统安装
  15. 使用JAVA开发连连看游戏
  16. python requests 代理ip被禁_python requests 测试代理ip是否生效
  17. 英语论文应该怎么查重?
  18. 进制怎么用计算机算,Win10计算器怎么算二进制,win10计算器二进制使用教程
  19. Windows 10下安装Elementary OS双系统
  20. asp毕业设计——基于asp+access的博客网站设计与实现(毕业论文+程序源码)——博客网站

热门文章

  1. python函数求n年后本息_Python自定义函数计算给定日期是该年第几天的方法示例...
  2. 百度竞价排名曝光_企业入驻百度爱采购必须选好本地运营服务商
  3. oracle select输出dbms,PLSQL 中如何使用 dbms_output 输出结果
  4. python超时处理_Python如何实现让一个函数超时退出?
  5. 不支持给定路径的格式_剑指offer_12_矩阵中的路径
  6. CycleGAN详解与实现(采用tensorflow2.x实现)
  7. android传感器_Android传感器
  8. android单选按钮_Android单选按钮示例
  9. Python字符串isalpha()
  10. 熊猫DataFrame groupby()函数