Leetcode 407. Trapping Rain Water II
来源:互联网 发布:黄金分析软件怎么样? 编辑:程序博客网 时间:2024/05/16 05:11
https://leetcode.com/problems/trapping-rain-water-ii/description/
感谢室友在思路上的提点
Given an m x n matrix of positive integers representing the height of each unit cell in a 2D elevation map, compute the volume of water it is able to trap after raining.
Note:
Both m and n are less than 110. The height of each unit cell is greater than 0 and is less than 20,000.
Example:
Given the following 3x6 height map:[ [1,4,3,1,3,2], [3,2,1,3,2,4], [2,3,3,2,3,1]]Return 4.
The above image represents the elevation map [[1,4,3,1,3,2],[3,2,1,3,2,4],[2,3,3,2,3,1]] before the rain.
After the rain, water are trapped between the blocks. The total volume of water trapped is 4.
要求坑里的水,首先得知道哪些是坑,可以知道的是边缘的一定不是坑,水一定会在边缘处流出,然后边缘临近的位置假如比边缘高,那么这个位置的水就会留到边缘处,然后流出去,所以这个位置成为了新的边缘。
那么最简单的方法就是先从边缘开始都广搜一波,标记边缘,那么这个图就会收缩,没有被标记到的就是我们的水坑,然后统计这里的水量,这里就需要再次广搜以确定每个坑的最低的边缘高度,然后结合原图就能统计完成了,思路很简单很暴力。
换个角度看,能不能在收缩的时候把坑的最低边缘高度确定下来?可以确定的是,水一定是从最低的边缘流出来的,假如我们知道每个边缘的最低高度low,假如附近没坑,那么水就是这里流出来,假如有坑ij,那么坑一定会被填满,填的水量就是low.height-heightMap[i][j]
,然后这个被填满的坑不就成为了新的边缘了吗?这样我们得出了新的收缩方式,不再是单纯去确定是不是坑,而是在收缩的过程中,把坑填满当作边缘就好了。也就是重复寻找边缘中的最小值然后收缩附近一格,是坑就填成边缘,不是就直接当作边缘。最小堆就能实现快速找最小,所以用个优先队列。
class Solution {public: int trapRainWater(vector<vector<int>>& heightMap) { int n = heightMap.size(); if (n == 0) return 0; int m = heightMap[0].size(); priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> que; int visit[n+1][m+1] = {0}; // 标记过的都是边缘 for (int i = 0; i < n; ++i) { for (int j = 0; j < m; ++j) { if (i == 0 || j == 0 || i == n-1 || j == m-1) { que.push(make_pair(heightMap[i][j], i * m + j)); visit[i][j] = 1; } } } int dx[4] = {-1,1,0,0}; int dy[4] = {0,0,-1,1}; int res = 0; while (!que.empty()) { pair<int, int> low = que.top(); que.pop(); int i = low.second / m; int j = low.second % m; // 四个方向收缩一格 for (int k = 0; k < 4; ++k) { int ii = i + dx[k]; int jj = j + dy[k]; if (ii > 0 && ii < n && jj > 0 && jj < m && !visit[ii][jj]) { visit[ii][jj] = 1; // 大于则是坑 if (low.first > heightMap[ii][jj]) res += low.first - heightMap[ii][jj]; // max就是填坑做边缘或者非坑直接做边缘 que.push(make_pair(max(low.first, heightMap[ii][jj]), ii * m + jj)); } } } return res; }};
- Leetcode 407. Trapping Rain Water II
- LeetCode 407. Trapping Rain Water II
- [LeetCode]407. Trapping Rain Water II
- Leetcode 407. Trapping Rain Water II
- [leetcode]407. Trapping Rain Water II
- leetcode 407. Trapping Rain Water II
- leetcode 407. Trapping Rain Water II
- Leetcode 407. Trapping Rain Water II
- LeetCode 407. Trapping Rain Water II
- 407. Trapping Rain Water II
- 407. Trapping Rain Water II
- 407. Trapping Rain Water II
- 407. Trapping Rain Water II
- 407. Trapping Rain Water II
- 407. Trapping Rain Water II
- [leetcode] 407. Trapping Rain Water II 解题报告
- [Leetcode] 407. Trapping Rain Water II 解题报告
- Leetcode 407 Trapping Rain Water II
- C++ Primer 学习笔记(第二章)
- 相对和绝对路径,cd命令,创建和删除目录mkdir/rmdir, rm命令
- Android蓝牙开发小实例—打开关闭蓝牙
- 7-4 银行排队问题之单窗口“夹塞”版
- PTA 7-5 银行排队问题之单队列多窗口服务
- Leetcode 407. Trapping Rain Water II
- PTA 7-6 银行排队问题之单队列多窗口加VIP服务
- jq 在元素后面或者外部增加HTML代码
- PTA 7-8 修理牧场
- Duilib技巧:背景图片平铺
- 3dsmax 第一课
- PTA 7-9 目录树
- PTA 7-10 旅游规划
- IT定律二三事