题目地址:
https://leetcode.com/problems/trapping-rain-water-ii/
给定一个二维矩阵
A
A
A,每个位置表示这个位置的柱子高度。问下雨的时候这个矩阵上面最多能盛多少水。
思路参考https://blog.youkuaiyun.com/qq_46105170/article/details/108575830。代码如下:
import java.util.Objects;
import java.util.PriorityQueue;
public class Solution {
class Pair {
int x, y, h;
public Pair(int x, int y, int h) {
this.x = x;
this.y = y;
this.h = h;
}
}
public int trapRainWater(int[][] heightMap) {
PriorityQueue<Pair> minHeap = new PriorityQueue<>((p1, p2) -> Integer.compare(p1.h, p2.h));
int m = heightMap.length, n = heightMap[0].length;
// 先把外围一圈加入堆中,并标记为已访问
boolean[][] visited = new boolean[m][n];
for (int i = 0; i < m; i++) {
minHeap.offer(new Pair(i, 0, heightMap[i][0]));
visited[i][0] = true;
minHeap.offer(new Pair(i, n - 1, heightMap[i][n - 1]));
visited[i][n - 1] = true;
}
for (int i = 0; i < n; i++) {
minHeap.offer(new Pair(0, i, heightMap[0][i]));
visited[0][i] = true;
minHeap.offer(new Pair(m - 1, i, heightMap[m - 1][i]));
visited[m - 1][i] = true;
}
// res统计盛的水
int res = 0;
int[] d = {1, 0, -1, 0, 1};
while (!minHeap.isEmpty()) {
Pair cur = minHeap.poll();
for (int i = 0; i < 4; i++) {
int nextX = cur.x + d[i], nextY = cur.y + d[i + 1];
if (0 <= nextX && nextX < m && 0 <= nextY && nextY < n) {
if (visited[nextX][nextY]) {
continue;
}
res += Math.max(0, cur.h - heightMap[nextX][nextY]);
Pair next = new Pair(nextX, nextY, Math.max(cur.h, heightMap[nextX][nextY]));
visited[nextX][nextY] = true;
minHeap.offer(next);
}
}
}
return res;
}
}
时间复杂度 O ( m n log ( m n ) ) O(mn\log (mn)) O(mnlog(mn)),空间 O ( m n ) O(mn) O(mn)。