LeetCode 407. 接雨水 II (优先队列)
从最外圈开始不断向内遍历,如果内部的高度小于外部的高度,则证明该位置可以蓄水,否则不能,水会顺着该外圈流出去。
每次都处理外圈高度最小的那个位置 a,遍历它的四周。
如果它旁边的某个位置 b 高度小于 a,则证明 b 可以蓄水,因为 a 已经是四周最小的高度了,则 b 可以蓄水的大小就是 height(a)-height(b)
如果 b 的高度大于 a 则不能蓄水,水会顺着 a 流出去。
处理完 a 周围的所有位置后,把 a 删除,把 a 周围的位置当做新的边界。
其中,如果 a 周围的高度有小于 a 的,就补齐到 a,因为其是被 a 围住的,注水时高度不可能小 a。而如果高度大于 a 不用处理。
具体实现,先把最外圈的所有高度压入优先队列,然后每次取高度最小的去处理就可以了。
理解了还是觉得有点抽象。有一说一。其他题解一个都没看懂。
struct node { int x, y, h; node() {} node(int x, int y, int h): x(x), y(y), h(h) {} bool operator<(const node &rhs) const { return h > rhs.h; // 保证优先队列是小顶堆 } }; class Solution { public: int trapRainWater(vector<vector<int>>& heightMap) { priority_queue<node> q; int n = heightMap.size(), m = heightMap[0].size(); vector<vector<int>> visited(n, vector<int>(m, 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) { q.emplace(i, j, heightMap[i][j]); visited[i][j] = 1; } } } int dir[4][2] = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}}; int ans = 0; while (q.size()) { node cur = q.top(); q.pop(); for (int i = 0; i < 4; i++) { int nx = cur.x + dir[i][0]; int ny = cur.y + dir[i][1]; if (nx < n && nx >= 0 && ny < m && ny >= 0 && !visited[nx][ny]) { if (heightMap[nx][ny] < cur.h) { ans += cur.h - heightMap[nx][ny]; q.emplace(nx, ny, cur.h); } else { q.emplace(nx, ny, heightMap[nx][ny]); } visited[nx][ny] = 1; } } } return ans; } };
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架