[LeetCode] Trapping Rain Water II 题解
题意
思路
我一开始想的时候只考虑到一个结点周围的边界的情况,并没有考虑到边界的高度其实影响到所有的结点盛水的高度。
我们可以发现,中间是否能够盛水取决于边界是否足够高于里面的高度,所以这必然是一个从外到内,从小到大的一个过程。因为优先队列必然首先访问的是边界中最小的高度,如果周围小于这个高度那么必然是存在可以盛水的地方,就算是没有也没有任何的损失,只是更新了高度,但是队列依然会从高度小的结点开始访问;
实现
typedef struct node {
int x, y;
node(int x, int y) : x(x), y(y) {}
} Node;
class Solution {
public:
/**
[1,4,3,1,3,2],
[3,2,1,3,2,4],
[2,3,3,2,3,1]
发现:四条边都不可以存储水,,也就是在这个二维数组中才能存储水
从第二列开始,去找四周里面大于它自己的第一个数(前提是三面或者两面是大于它的),然后减去自己
*/
int trapRainWater(vector<vector<int>>& heightMap) {
if (heightMap.size() == 0) {
return 0;
}
else if (heightMap.size() < 3 || heightMap[0].size() < 3) {
return 0;
}
int row = heightMap.size();
int col = heightMap[0].size();
queue<Node*> queues;
vector<vector<int>> visited(row, vector<int>(col, 0));
Node *start = new Node(1, 1);
visited[1][1] = 1;
queues.push(start);
auto state_center = [&](int x, int y) {
if (x >= 1 && x <= heightMap.size()-2 && y >= 1 && y <= heightMap[0].size()-2) {
return true;
}
return false;
};
//上下左右
vector< vector<int>> layouts = {{1, 0}, {-1, 0}, {0, -1}, {0, 1}};
int sum = 0;
while (!queues.empty()) {
Node* node = queues.front();
queues.pop();
// 取中间的值
if (state_center(node->x, node->y)) {
vector<int> priority;
bool isfinished = true;
// 找周围四个点
for (int i = 0; i < layouts.size(); i++) {
vector<int> temp = layouts[i];
int newx = node->x + temp[0];
int newy = node->y + temp[1];
// 不符合条件
if (heightMap[newx][newy] > heightMap[node->x][node->y] && (newx == 0 || newx == heightMap.size()-1) &&
(newy == 0 || newy == heightMap[0].size()-1)) {
isfinished = false;
break;
}
else if (newx == 0 || newx == heightMap.size()-1 || newy == 0 || newy == heightMap[0].size()-1) {
priority.push_back(heightMap[newx][newy]);
continue;
}
Node *newnode = new Node(newx, newy);
if (!visited[newx][newy]) {
queues.push(newnode);
visited[newx][newy] = 1;
}
}
if (isfinished) {
sort(priority.begin(), priority.end());
int val = heightMap[node->x][node->y];
for (int i = 0; i < priority.size(); i++) {
if (priority[i] >= val) {
sum += priority[i] - val;
break;
}
}
}
}
}
return sum;
}
/**
* 存放水的高度取决于周围的最小高度,BFS的思想
* 首先存取四面的高度,用优先队列去存储,保证取出来的一定是队列中的最小值
* 取较大的高度,如果存在没访问过并且小于当前最小高度的,则计算盛水高度,并且将该结点设置成已访问
*
* @param heightMap
* @return
*/
int trapRainWater2(vector<vector<int>>& heightMap) {
if (heightMap.size() == 0) {
return 0;
}
int row = heightMap.size();
int col = heightMap[0].size();
struct cmp {
bool operator()(pair<int, int> a, pair<int, int> b) {
if (a.first > b.first) {
return true;
}
else {
return false;
}
}
};
priority_queue<pair<int, int>, vector<pair<int, int>>, cmp> queue;
vector<vector<int>> visited(row, vector<int>(col, 0));
// 将外围的高度加入到队列中,找出最小值
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
if (i == 0 || i == row-1 || j == 0 || j == col-1) {
queue.push(make_pair(heightMap[i][j], i * col + j));
visited[i][j] = 1;
}
}
}
vector< vector<int>> layouts = {{1, 0}, {-1, 0}, {0, -1}, {0, 1}};
int maxHeight = INT_MIN, sum = 0;
while (!queue.empty()) {
pair<int, int> content = queue.top();
queue.pop();
int height = content.first;
int x = content.second / col;
int y = content.second % col;
maxHeight = max(maxHeight, height);
for (auto temp : layouts) {
int newx = x + temp[0];
int newy = y + temp[1];
if (newx < 0 || newx >= row || newy < 0 || newy >= col || visited[newx][newy]) {
continue;
}
if (heightMap[newx][newy] < maxHeight) {
sum += maxHeight - heightMap[newx][newy];
}
visited[newx][newy] = 1;
queue.push(make_pair(heightMap[newx][newy], newx * col + newy));
}
}
return sum;
}
void test() {
vector< vector<int>> water = {
{12,13,1,12},
{13,4,13,12},
{13,8,10,12},
{12,13,12,12},
{13,13,13,13}
};
int result = this->trapRainWater2(water);
cout << "sum:" << result << endl;
}
};
[LeetCode] Trapping Rain Water II 题解的更多相关文章
- [LeetCode] Trapping Rain Water II 收集雨水之二
Given an m x n matrix of positive integers representing the height of each unit cell in a 2D elevati ...
- Leetcode: Trapping Rain Water II
Given an m x n matrix of positive integers representing the height of each unit cell in a 2D elevati ...
- leetcode 11. Container With Most Water 、42. Trapping Rain Water 、238. Product of Array Except Self 、407. Trapping Rain Water II
11. Container With Most Water https://www.cnblogs.com/grandyang/p/4455109.html 用双指针向中间滑动,较小的高度就作为当前情 ...
- [LeetCode] Trapping Rain Water 收集雨水
Given n non-negative integers representing an elevation map where the width of each bar is 1, comput ...
- [LeetCode] 407. Trapping Rain Water II 收集雨水之二
Given an m x n matrix of positive integers representing the height of each unit cell in a 2D elevati ...
- [LeetCode] 407. Trapping Rain Water II 收集雨水 II
Given an m x n matrix of positive integers representing the height of each unit cell in a 2D elevati ...
- LeetCode: Trapping Rain Water 解题报告
https://oj.leetcode.com/problems/trapping-rain-water/ Trapping Rain WaterGiven n non-negative intege ...
- [Swift]LeetCode407. 接雨水 II | Trapping Rain Water II
Given an m x n matrix of positive integers representing the height of each unit cell in a 2D elevati ...
- [leetcode]Trapping Rain Water @ Python
原题地址:https://oj.leetcode.com/problems/trapping-rain-water/ 题意: Given n non-negative integers represe ...
随机推荐
- IE6支持透明PNG图片解决方案:DD_belatedPNG.js
DD_belatedPNG.js 是一个能是IE6支持p显示ng透明图片,而且还支持背景循环(background-repeat)和定位(backgrond-position) ,支持focus,Ho ...
- DotNet加密方式解析--非对称加密
新年新气象,也希望新年可以挣大钱.不管今年年底会不会跟去年一样,满怀抱负却又壮志未酬.(不过没事,我已为各位卜上一卦,卦象显示各位都能挣钱...).已经上班两天了,公司大部分人还在休假,而我早已上班, ...
- 使用python制作ArcGIS插件(4)界面交互
使用python制作ArcGIS插件(4)界面交互 by 李远祥 插件界面部分,除了一开始在设计器中设计的这些界面元素之外,还可以与操作系统进行一些输入输出的交互,这部分的实现全部在pythonadd ...
- TFS2010升级至TFS2013完全指南
一.背景: 公司已使用tfs2010很长时间,目前随着公司的发展,项目越来越少,而产品越来越多,采用的开发模式,也逐渐从瀑布式.迭代式转向敏捷开发.为了更好的支持产品研发,决定将tfs ...
- CentOS 7 网卡命名修改为ethx格式
Linux 操作系统的网卡设备的传统命名方式是 eth0.eth1.eth2等,而 CentOS7 提供了不同的命名规则,默认是基于固件.拓扑.位置信息来分配.这样做的优点是命名全自动的.可预知的,缺 ...
- EF+SQLSERVER控制并发下抢红包减余额(改进)
最近几年想必大家一听到哪里有抢红包可以抢,马上会拿起手机点去~~~~然后问题来了... 如何控制在同一时间保证数据库中扣减红包余额不会出错.之前我们的做法是直接锁程序,这样子带来的坏处就是等待时间太长 ...
- JavaWeb验证码的使用
在Java Web开发中,我们经常需要使用到验证码功能,一般情况下,我们可以将产生的验证码保存到服务器端中的session中,这种方式中,是使用服务器来保证验证码的功能.另外,我们也可以采用js产生验 ...
- 360随身wifi无法使用临时解决方案大全
360随身wifi在绝大多数情况下都是可以正常使用的,但在极少数系统或网络环境下可能会出现异常,如系统服务缺失.公司网络限制.少数校园网客户端限制等等: 360攻城师正在积极努力解决 ...
- 2017-2-24 C#基础 for循环的嵌套
用几个练习题演示一下for循环的嵌套 1.打印以下图形 ★★★★★★★★★★★★★★★ namespace _2017_2_24_for循环的嵌套 { class Program { static v ...
- Matlab将三维变量分割为多个二维变量的方法
最近在处理 Matlab 中的三维矩阵的时候,遇到了一个问题: 假如m 为 5*5*5的矩阵,如果以第三个维度为基础,分割为5个不同的矩阵 m1,m2,m3,m4,应该如何解决? 解决方法:eval函 ...