JavaScript Solution Summary
Solution #1 (Using DFS)\n\n/**\n * @param {number[][]} heightMap\n * @return {number}\n */\nvar trapRainWater = function(heightMap) {\n    let water = 0, minh =
Solution #1 (Using DFS)\n```\n/**\n * @param {number[][]} heightMap\n * @return {number}\n */\nvar trapRainWater = function(heightMap) {\n    let water = 0, minh = Array(heightMap.length).fill([]);\n    for(let i in minh) minh[i] = new Array(heightMap[0].length).fill(0);\n    // return minh;\n    if(heightMap.length<3||heightMap[0].length<3) return water;\n\tfor(let i=0;i<heightMap.length;i++){\n\t\tminh[i][0] = heightMap[i][0];\n\t\tminh[i][heightMap[0].length-1] = heightMap[i][heightMap[0].length-1]; \n\t}\n\tfor(let j=0;j<heightMap[0].length;j++){\n\t\tminh[0][j] = heightMap[0][j];\n\t\tminh[heightMap.length-1][j] = heightMap[heightMap.length-1][j];    \t\t\t\n\t}\n\tfor(let i=1;i<heightMap.length-1;i++)\n\t\tfor(let j=1;j<heightMap[0].length-1;j++){\n\t\t\tlet min = Number.MAX_VALUE;\n\t\t\tif(minh[i-1][j]!==0) min = Math.min(min, minh[i-1][j]);\n\t\t\tif(minh[i+1][j]!==0) min = Math.min(min, minh[i+1][j]);\n\t\t\tif(minh[i][j+1]!==0) min = Math.min(min, minh[i][j+1]);\n\t\t\tif(minh[i][j-1]!==0) min = Math.min(min, minh[i][j-1]);    \t\t\t\n\t\t\tminh[i][j] = Math.max(heightMap[i][j], min);\n\t\t\t//pass by\n\t\t\tdfs(heightMap, minh, minh[i][j], i-1, j);    \t \n\t    \tdfs(heightMap, minh, minh[i][j], i, j-1);    \t    \t\n\t\t}\n\t\n\tfor(let i=1;i<heightMap.length-1;i++)\n\t\tfor(let j=1;j<heightMap[0].length-1;j++){\n\t\t\twater += minh[i][j]-heightMap[i][j];\n\t\t}\n\t\n\treturn water;\n};\n\nvar dfs = function(matrix, minh, h, i, j){\n\tif(i===0||i==matrix.length-1||j===0||j==matrix[0].length-1) return;\n\tif(minh[i][j]===0) return;\n\tif(minh[i][j]>h&&minh[i][j]!=matrix[i][j]){\n\t\tminh[i][j] = Math.max(matrix[i][j], h); \n\t\tdfs(matrix, minh, minh[i][j], i-1, j);\n    \tdfs(matrix, minh, minh[i][j], i+1, j);\n    \tdfs(matrix, minh, minh[i][j], i, j-1);\n    \tdfs(matrix, minh, minh[i][j], i, j+1);\n\t}    \t\n};\n```\n\nSolution #2 (Using Queue)\n```\n/**\n * @param {number[][]} heightMap\n * @return {number}\n */\nvar trapRainWater = function(heightMap) {\n    var q = new myQueue();\n    var visited = [];\n    var x = heightMap.length;\n    if(!x) {\n        return 0;\n    }\n    var y = heightMap[0].length;\n    if(!y) {\n        return 0;\n    }\n    //console.log("X=" + x + ", Y=" + y);\n    var sum = 0;\n    for(var i = 0; i < x; i++) {\n        var temp = Array(y).fill(false);\n        visited.push(temp);\n    }\n    for(var j = 0; j < y; j++) {\n        q.push({value: heightMap[0][j], loc: [0, j]});\n        visited[0][j] = true;\n        q.push({value: heightMap[x-1][j], loc: [x-1, j]});\n        visited[x-1][j] = true;\n    }\n    for(var i = 1; i < x-1; i++) {\n        q.push({value: heightMap[i][0], loc: [i, 0]});\n        visited[i][0] = true;\n        q.push({value: heightMap[i][y-1], loc: [i, y-1]});\n        visited[i][y-1] = true;\n    }\n    //q.print();\n    while(!q.empty()) {\n        var temp = q.pop();\n        //console.log("process " + JSON.stringify(temp));\n        var locx = temp.loc[0];\n        var locy = temp.loc[1];\n        var v = temp.value;\n        if(locx !== 0) {\n            if(!visited[locx-1][locy]) {\n                visited[locx-1][locy] = true;\n                if(heightMap[locx-1][locy] > v) {\n                    q.push({value:heightMap[locx-1][locy], loc:[locx-1, locy]});\n                    //console.log("Push11 " + heightMap[locx][locy+1] + " to [" + locx + ", " + locy + "]" );\n                } else {\n                    sum += v - heightMap[locx-1][locy];\n                    q.push({value:v, loc:[locx-1, locy]});\n                    //console.log("Push12 " + v + " to [" + locx + ", " + locy + "]" );\n                }\n            }\n        }\n        if(locx !== x-1) {\n            if(!visited[locx+1][locy]) {\n                visited[locx+1][locy] = true;\n                if(heightMap[locx+1][locy] > v) {\n                    q.push({value:heightMap[locx+1][locy], loc:[locx+1, locy]});\n                    //console.log("Push21 " + heightMap[locx][locy+1] + " to [" + locx + ", " + locy + "]" );\n                } else {\n                    sum += v - heightMap[locx+1][locy];\n                    q.push({value:v, loc:[locx+1, locy]});\n                    //console.log("Push22 " + v + " to [" + locx + ", " + locy + "]" );\n                }\n            }\n        }\n        if(locy !== 0) {\n            if(!visited[locx][locy-1]) {\n                visited[locx][locy-1] = true;\n                if(heightMap[locx][locy-1] > v) {\n                    q.push({value:heightMap[locx][locy-1], loc:[locx, locy-1]});\n                    //console.log("Push31 " + heightMap[locx][locy-1] + " to [" + locx + ", " + locy + "]" );\n                } else {\n                    sum += v - heightMap[locx][locy-1];\n                    q.push({value:v, loc:[locx, locy-1]});\n                    //console.log("Push32 " + v + " to [" + locx + ", " + locy + "]" );\n                }\n            }\n        }\n        if(locy !== y-1) {\n            if(!visited[locx][locy+1]) {\n                visited[locx][locy+1] = true;\n                if(heightMap[locx][locy+1] > v) {\n                    q.push({value:heightMap[locx][locy+1], loc:[locx, locy+1]});\n                    //console.log("Push41 " + heightMap[locx][locy+1] + " to [" + locx + ", " + locy + "]" );\n                } else {\n                    sum += v - heightMap[locx][locy+1];\n                    q.push({value:v, loc:[locx, locy+1]});\n                    //console.log("Push42 " + v + " to [" + locx + ", " + locy + "]" );\n                }\n\n            }\n        }\n    }\n    return sum;\n};\n\nvar myQueue = function() {\n    this.cache = [];\n}\n\nmyQueue.prototype.push = function(n) {\n    var i;\n    for(i = 0; i < this.cache.length; i++) {\n        if(n.value < this.cache[i].value) {\n            break;\n        }\n    }\n    this.cache.splice(i, 0, n);\n};\n\nmyQueue.prototype.pop = function() {\n   return this.cache.shift(); \n};\n\nmyQueue.prototype.empty = function() {\n    return this.cache.length === 0? true:false;\n}\n\nmyQueue.prototype.print = function() {\n    console.log(JSON.stringify(this.cache));\n}\n```\n\n\nSolution #3 (Using Heap)\n```\nfunction Heap(less) {\n    this.heap = []\n    this.less = less\n}\n\nHeap.prototype.exch = function(i, j) {\n    [this.heap[i], this.heap[j]] = [this.heap[j], this.heap[i]]\n}\n\nHeap.prototype.parent = function(x) {\n    return (x-1) >> 1\n}\n\nHeap.prototype.swim = function(x) {\n    while (x>0) {\n        let p = this.parent(x)\n        // console.log(this.heap[p], this.heap[x], this.less(this.heap[p],this.heap[x]))\n        if (this.less(this.heap[p], this.heap[x])) {\n            this.exch(p, x)\n            x = p\n        } else {\n            break\n        }\n    }\n}\n\nHeap.prototype.sink = function(x) {\n    while(2*x+1<this.heap.length) {\n        let c = 2*x+1\n        if (c+1<this.heap.length && this.less(this.heap[c], this.heap[c+1])) {\n            c += 1\n        } \n        \n        if (this.less(this.heap[x], this.heap[c])) {\n            this.exch(x, c)\n            x = c\n        } else {\n            break\n        }\n    }\n}\n\nHeap.prototype.push = function(v) {\n    this.heap.push(v)\n    this.swim(this.heap.length-1)\n    // console.log(v, this.heap)\n}\n\nHeap.prototype.size = function() {\n    return this.heap.length\n}\n\nHeap.prototype.peak = function() {\n    return this.heap.length > 0 ? this.heap[0] : null\n}\n\nHeap.prototype.pop = function() {\n    let top = this.heap[0]\n    this.heap[0] = this.heap[this.heap.length-1]\n    this.heap.pop()\n    this.sink(0)\n    return top\n}\n/**\n * @param {number[][]} heightMap\n * @return {number}\n */\nvar trapRainWater = function(heightMap) {\n    if (!heightMap || !heightMap.length) {\n        return 0\n    }\n    let m = heightMap.length\n    let n = heightMap[0].length\n    \n    let marked = Array(m)\n    let minHeap = new Heap((v1, v2) => v2[2] < v1[2])\n    for (let i=0; i<m; i++) {\n        marked[i] = Array(n).fill(false)\n        for (let j=0; j<n; j++) {\n            if (i===0 || j === 0 || i === m-1 || j=== n-1) {\n                minHeap.push([i, j, heightMap[i][j]])\n                marked[i][j] = true\n            } \n        }\n    }\n    // console.log(minHeap.heap, marked)\n    let res = 0\n    let dirs = [[0, 1], [0, -1], [1, 0], [-1, 0]]\n    while (minHeap.size()) {\n        let c = minHeap.pop()\n        for (let d of dirs) {\n            dx = c[0] + d[0]\n            dy = c[1] + d[1]\n            if (dx>=0 && dx<m && dy>=0 && dy<n && !marked[dx][dy]) {\n                marked[dx][dy] = true\n                res += Math.max(0, c[2] - heightMap[dx][dy])\n                minHeap.push([dx, dy, Math.max(c[2], heightMap[dx][dy])])\n            }\n        }\n    }\n    \n    return res;\n    \n};\n```\n\nAt last, Thanks to all previous contributors.
[]