[Java] Clean Priority Queue solution with visualization
This is the visualisation:https://www.youtube.com/watch?v=cJayBq38VYw\n\nHere is the code:\n\nclass Solution {\n    public int trapRainWater(int[][] heightMap) 
This is the visualisation:https://www.youtube.com/watch?v=cJayBq38VYw\n\nHere is the code:\n```\nclass Solution {\n    public int trapRainWater(int[][] heightMap) {\n        if(heightMap==null || heightMap.length==0 || heightMap[0].length==0){return 0;}\n        PriorityQueue<Point> pq = getPQ();\n        HashSet<String> visited = new HashSet<>();\n        addMapBoundaryToPQ(heightMap, pq, visited);\n        int[][] dirs = new int[][]{{0,-1},{0,1},{-1,0},{1,0}};\n        int max = 0;\n        int answer = 0;\n        \n        while(!pq.isEmpty()){\n            Point cur = pq.remove();\n            max = Math.max(max, cur.val);\n            for(int[] dir:dirs){\n                int row_New = cur.row+dir[0];\n                int col_New = cur.col+dir[1];\n                if(canVisit(row_New, col_New, visited, heightMap)){\n                    if(heightMap[row_New][col_New]<max){\n                        answer+=(max-heightMap[row_New][col_New]);\n                    }\n                    pq.add(new Point(row_New, col_New, heightMap[row_New][col_New]));\n                    visited.add(row_New+"_"+col_New);\n                }\n            }\n        }\n        return answer;\n    }\n    public boolean canVisit(int row, int col, HashSet<String> visited, int[][] heightMap){\n        if(row<0 || row>=heightMap.length || col<0 || col>=heightMap[0].length){return false;}\n        if(visited.contains(row+"_"+col)){return false;}\n        return true;\n    }\n    \n    public PriorityQueue<Point> getPQ(){\n        PriorityQueue<Point> pq = new PriorityQueue<>(new Comparator<Point>(){\n            @Override\n            public int compare(Point a, Point b){\n                return a.val-b.val;\n            }\n        });\n        return pq;\n    }\n    public void addMapBoundaryToPQ(int[][] heightMap, PriorityQueue<Point> pq, HashSet<String> visited){\n        for(int i=0;i<heightMap.length;i++){\n            pq.add(new Point(i,0,heightMap[i][0]));\n            pq.add(new Point(i, heightMap[0].length-1, heightMap[i][heightMap[0].length-1]));\n            visited.add(i+"_"+0);\n            visited.add(i+"_"+(heightMap[0].length-1));\n        }\n        for(int i=1;i<heightMap[0].length-1;i++){\n            pq.add(new Point(0,i,heightMap[0][i]));\n            pq.add(new Point(heightMap.length-1, i, heightMap[heightMap.length-1][i]));\n            visited.add(0+"_"+i);\n            visited.add(heightMap.length-1+"_"+i);\n        } \n    }\n    class Point{\n        int row;\n        int col;\n        int val;\n        public Point(int row, int col, int val){\n            this.row = row;\n            this.col = col;\n            this.val = val;\n        }\n    }\n}\n```\n
[]