[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 ...
随机推荐
- Windows 10 IoT Core环境配置中的那些坑
我使用的设备是Raspberry Pi 3B,想来国内的嵌入式玩具应该还是树莓派最常见吧.这段时间一直在捣鼓Win10 IoT,结果发现,从安装一直到编码调试一路下来全都是坑.写这篇东西一个是为了备忘 ...
- win10环境下python3.5安装步骤
点我去Python官网下载 往下翻几页就能看到各种版本的Python,当前最新的是Python3.6,也没多大区别,我选择的是3.5.2 64位的,点击download 根据自己的电脑配置,我选择的是 ...
- Android中微信抢红包助手的实现
参考(感谢作者):http://www.jianshu.com/p/cd1cd53909d7 http://blog.csdn.net/jiangwei0910410003/article/detai ...
- 【小分享】Date对象封装,时间格式化函数time()
今天再来分享下Date的应用知识点 先看效果,类似于php里边的time('yyyy-mm-dd')用法,但是我这里没有完全依照php的参数格式来,如果有需要稍微修改一下就行. 首先,明确需要用到的参 ...
- Swift 内存管理详解
Swift内存管理: Swift 和 OC 用的都是ARC的内存管理机制,它们通过 ARC 可以很好的管理对象的回收,大部分的时候,程序猿无需关心 Swift 对象的回收. 注意: 只有引用类型变量所 ...
- 安卓TCP通信版本2
PC做服务器,安卓做客户端. 安卓获取输入框的内容并发送,然后等待接收服务器的消息 服务器先行开启,接收到客户端的数据,然后回复消息. 实现了对线程类的封装,通过按钮启动线程发送并接收 服务器代码(j ...
- 树莓派上搭建arduino开发环境
-------------还是博客园上面的格式看这舒服,不去新浪了------------- 为什么要在树莓派上开发arduino呢?总要把树莓派用起来嘛,不然老吃灰. 树莓派使用SSH时没有图形界面 ...
- 前端开发面试题总结之——HTML
______________________________________________________________________________________________ 相关知识点 ...
- HAProxy实战
实验目的 测试基于haproxy的反代和负载均衡配置 测试keepalived高可用haproxy的效果 实验要点 (1) 动静分离discuzx,动静都要基于负载均衡实现: (2) 进一步测试在ha ...
- python爬虫利器Selenium使用详解
简介: 用pyhon爬取动态页面时普通的urllib2无法实现,例如下面的京东首页,随着滚动条的下拉会加载新的内容,而urllib2就无法抓取这些内容,此时就需要今天的主角selenium. Sele ...