题意

题目

思路

我一开始想的时候只考虑到一个结点周围的边界的情况,并没有考虑到边界的高度其实影响到所有的结点盛水的高度。

我们可以发现,中间是否能够盛水取决于边界是否足够高于里面的高度,所以这必然是一个从外到内,从小到大的一个过程。因为优先队列必然首先访问的是边界中最小的高度,如果周围小于这个高度那么必然是存在可以盛水的地方,就算是没有也没有任何的损失,只是更新了高度,但是队列依然会从高度小的结点开始访问;

实现

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 题解的更多相关文章

  1. [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 ...

  2. 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 ...

  3. 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 用双指针向中间滑动,较小的高度就作为当前情 ...

  4. [LeetCode] Trapping Rain Water 收集雨水

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

  5. [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 ...

  6. [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 ...

  7. LeetCode: Trapping Rain Water 解题报告

    https://oj.leetcode.com/problems/trapping-rain-water/ Trapping Rain WaterGiven n non-negative intege ...

  8. [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 ...

  9. [leetcode]Trapping Rain Water @ Python

    原题地址:https://oj.leetcode.com/problems/trapping-rain-water/ 题意: Given n non-negative integers represe ...

随机推荐

  1. Java豆瓣电影爬虫——减少与数据库交互实现批量插入

    节前一个误操作把mysql中record表和movie表都清空了,显然我是没有做什么mysql备份的.所以,索性我把所有的表数据都清空的,一夜回到解放前…… 项目地址:https://github.c ...

  2. yii2 邮件发送(有图有真相)

    经典的密码找回方案是发送邮件到用户邮箱然后修改密码,下面利用yii2 高级版的mail功能,进行邮件的发送,如下图 1.在comm/config/main-local.php中添加 'mailer' ...

  3. Python单元测试PyUnit框架轻度整改

    原理 参考:单元测试原理 背景 年后有段时间没写代码了,所以趁着周末找了个python单元测试玩下,测试自己的Android应用.发现PyUnit虽然在单个脚本文件中添加多个测试用例,比如官网提供的方 ...

  4. 一个普通底层.NET程序员关于职场瓶颈期的思考,辗转自我提升/跳槽/转行之间

    徒有工龄,没技术没学历没平台没家底,工作几年,无车无房无存款还前景不明. 时常有身边的亲友问怎么学开发怎么转互联网,说起IT行业都说工资高,动辄月薪上万动辄年薪几十万. 再看看自己,我可能是假的程序员 ...

  5. C#类详解

    类: 类是一种数据结构,它可以包含数据成员(常数和字段).函数成员(方法.属性.事件.索引器.运算符实例.构造函数静态构造函数和析构函数),以及嵌套类型.类类型支持继承,继承是一种机制,它使派生类可以 ...

  6. java初级开发程序员(第三单元)

    1.if基本选择结构: 语法: if(条件){     //程序执行时,先判断条件.当结果为true(真)时,程序先执行大括号的代码块,再执行if结构(即{}部分)后面的代码.当结果为false(假) ...

  7. BZOJ 1877: [SDOI2009]晨跑(费用流)

    看到要求两个量就下意识的想到了费用流= =,先把一个点拆成两个点就能够解决一个的只经过一次的限制 CODE: #include<cstdio>#include<iostream> ...

  8. 用js写出光棒效应的两种方法与jquery的两中方法

    <script src="js/jQuery1.11.1.js" type="text/javascript"></script> &l ...

  9. JAVA三大特性之三——多态

    作为JAVA的三大特性之一,多态性是很多人都没有弄清楚的一个重要特性,今天我就来从我所理解的角度来说一下. 首先,从他的字面意思来理解,多态,从其字面来理解就是多种形态,多种表现形式.根据这些,我最能 ...

  10. bootstrap select2 参数详解

    Select2使用示例地址: https://select2.github.io/examples.html Select2参数文档说明: https://select2.github.io/opti ...