力扣 407 接雨水2
题目可以自己去力扣看。
/*** @param {number[][]} heightMap* @return {number}*/var trapRainWater = function (heightMap) {if (heightMap.length <= 2 || heightMap[0].length <= 2) {return 0;}const n = heightMap.lengthconst m = heightMap[0].lengthlet vis = {}let queue = new PriorityQueue()let res = 0// 把边缘点加入优先队列for (let i = 0; i < n; i++) {vis[i + ',' + 0] = true;queue.add([heightMap[i][0], i, 0])vis[i + ',' + (m - 1)] = true;queue.add([heightMap[i][m - 1], i, m - 1])}for (let i = 1; i < m - 1; i++) {vis[0 + ',' + i] = true;queue.add([heightMap[0][i], 0, i])vis[(n - 1) + ',' + i] = true;queue.add([heightMap[n - 1][i], n - 1, i])}// 不断更新接水点while (queue.size()) {let [height, curN, curM] = queue.delete()// 访问相邻点let x = curNlet y = curM + 1if (y < m) {updateNode(x, y, height)}y = curM - 1if (y >= 0) {updateNode(x, y, height)}y = curMx = curN - 1if (x >= 0) {updateNode(x, y, height)}x = curN + 1if (x < n) {updateNode(x, y, height)}}return res;// 更新节点信息,如果没访问过就把节点推入优先队列function updateNode(x, y, height) {if (!vis[x + ',' + y]) {vis[x + ',' + y] = trueif (heightMap[x][y] < height) {res += (height - heightMap[x][y])}queue.add([Math.max(height, heightMap[x][y]), x, y])}}};// 优先队列class PriorityQueue {constructor() {this.arr = [];}shiftMinUp() { // 自底向上调整const { arr } = this;let i = arr.length - 1;let j = ~~((i + 1) / 2) - 1;let temp = arr[i];while (j >= 0) {if (temp[0] < arr[j][0]) {arr[i] = arr[j];} else {break;}i = j;j = j = ~~((j + 1) / 2) - 1;}arr[i] = temp;}shiftDownMin() { // 自顶向下调整const { arr } = this;if (!arr.length) {return arr;}let i = 0;let j = 2 * i + 1;let temp = arr[0];while (j < arr.length) {if (j < arr.length - 1 && arr[j][0] > arr[j + 1][0]) {j++;}if (temp[0] > arr[j][0]) {arr[i] = arr[j];} else {break;}i = j;j = j * 2 + 1;}arr[i] = temp;}add(num) { // 插入元素的时候在数组最后,也就是在叶子节点,需要往上调整位置const { arr } = this;arr.push(num);this.shiftMinUp();}delete() { // 删除时把队尾放到队首,此时可以从上到下调整位置const { arr } = this;let d = arr[0];arr[0] = arr[arr.length - 1];arr.pop()this.shiftDownMin();return d;}size() {return this.arr.length;}get() {return this.arr[0];}}
