题意

题目

思路

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

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

实现

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;}
};

参考文章

转载于:https://www.cnblogs.com/George1994/p/6592847.html

[LeetCode] Trapping Rain Water II 题解相关推荐

  1. 【重点:BFS】LeetCode 407. Trapping Rain Water II

    LeetCode 407. Trapping Rain Water II 博客转载自:http://www.cnblogs.com/grandyang/p/5928987.html [太难了,被智商碾 ...

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

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

  3. [leetcode]Trapping Rain Water @ Python

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

  4. Lintcode363 Trapping Rain Water solution 题解

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

  5. [LeetCode]Trapping Rain Water

    题目描述:(链接) Given n non-negative integers representing an elevation map where the width of each bar is ...

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

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

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

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

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

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

  9. LeetCode 42 Trapping Rain Water 收集雨水

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

  10. Leetcode 动态规划 Trapping Rain Water

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

最新文章

  1. JZOJ 5643. 【NOI2018模拟4.10】最小代价
  2. Cpp 对象模型探索 / 对象的虚函数表指针的位置
  3. 在Windows Server 2008的桌面上显示“我的电脑”“网上邻居”等图标?
  4. 利用WinPcap技术捕获数据包
  5. 如何清理 Weblogic Server 缓存
  6. 《构建之法》 读书笔记(4)
  7. 字符去多余空格_【Excel技巧】批量去空格删换行,用这两个函数简单又快速
  8. linux编译lnx文件命令_Linux常用命令手册
  9. WordPress登陆插件Erphplogin Pro QQ登陆/微博/微信登录/弹窗登录
  10. 豆瓣网络爬虫-java网络爬虫[验证码模拟登陆]详细介绍
  11. 解决datagridview 横向的scrollbar不显示
  12. [汇编语言计算机原理] 带开机音乐,速度、进度和行驶方向显示的出租出计费系统设计
  13. 北京系统集成项目经理考前培训
  14. EXCEL 小tips
  15. 最后防线:三款开源HIDS功能对比评估
  16. 主流的企业级虚拟化解决方案
  17. 学物理可以让我们永远年轻吗?
  18. Octave工具学习
  19. AWGN信道下的香农限
  20. C语言:十进制转十六进制并组合输出

热门文章

  1. rabbitmq消息持久化,避免异常情况下,消息会丢失
  2. input 密码框调出手机的数字键盘
  3. 系统字体大小导致rem布局变大
  4. MySQL Binlog--binlog_format参数
  5. 适配器模式 - 上厕所案例
  6. 模仿qq空间或朋友圈发布动态、评论动态、回复评论、删除动态或评论的功能(下)(核心部分)...
  7. 洛谷1004方格取数
  8. 5. DOM解析XML
  9. xcode6 使用MJRefresh
  10. C# 性能优化之斤斤计较篇 一