Trapping Rain Water II Leetcode

Given an m x n matrix of positive integers representing the height of each unit cell in a 2D elevation map, compute the volume of water it is able to trap after raining.

Note:
Both m and n are less than 110. The height of each unit cell is greater than 0 and is less than 20,000.

Example:

Given the following 3x6 height map:
[
  [1,4,3,1,3,2],
  [3,2,1,3,2,4],
  [2,3,3,2,3,1]
]

Return 4.

 


The above image represents the elevation map [[1,4,3,1,3,2],[3,2,1,3,2,4],[2,3,3,2,3,1]] before the rain.


After the rain, water are trapped between the blocks. The total volume of water trapped is 4.

 
 
这道题才算hard,看着就让人眼晕的那种。。。代码的确改了半天,思路比较清晰但不是这里忘记就是那里忘记。。。而且写的挺丑的。
需要注意的点有:
每次算出这个点能装水,不要忘记把本个点放到heap里同时要把本个点标记为已经访问过了。
每次放heap里面放点的时候,如果当前点小于桶边的点,要放当前点的坐标,桶边点的高度,因为是按照最高高度装水的。
public class Solution {
    public int trapRainWater(int[][] heightMap) {
        if (heightMap == null || heightMap.length == 0) {
            return 0;
        }
        int m = heightMap.length;
        int n = heightMap[0].length;
        int[][] visited = new int[m][n];
        int count = 0;
        PriorityQueue<Cell> pq = new PriorityQueue<>(new CellComparator());
        for (int i = 0; i < heightMap.length; i++) {
            Cell c = new Cell(i, 0, heightMap[i][0]);
            Cell d = new Cell(i, heightMap[i].length - 1, heightMap[i][heightMap[i].length - 1]);
            pq.offer(c);
            pq.offer(d);
            visited[i][0] = 1;
            visited[i][heightMap[i].length - 1] = 1;
        }
        for (int i = 0; i < heightMap[0].length; i++) {
            Cell c = new Cell(0, i, heightMap[0][i]);
            Cell d = new Cell(heightMap.length - 1, i, heightMap[heightMap.length - 1][i]);
            pq.offer(c);
            pq.offer(d);
            visited[0][i] = 1;
            visited[heightMap.length - 1][i] = 1;
        }
        while (!pq.isEmpty()) {
            Cell c = (Cell) pq.poll();
            if (c.x - 1 >= 0 && visited[c.x - 1][c.y] != 1) {
                Cell nc = null;
                if (heightMap[c.x - 1][c.y] >= c.value) {
                    nc = new Cell(c.x - 1, c.y, heightMap[c.x - 1][c.y]);
                } else {
                    count += c.value - heightMap[c.x - 1][c.y];
                    nc = new Cell(c.x - 1, c.y, c.value);
                }
                pq.offer(nc);
                visited[c.x - 1][c.y] = 1;
            }
            
            if (c.x + 1 < m && visited[c.x + 1][c.y] != 1) {
                Cell nc = null;
                if (heightMap[c.x + 1][c.y] >= c.value) {
                    nc = new Cell(c.x + 1, c.y, heightMap[c.x + 1][c.y]);
                } else {
                    count += c.value - heightMap[c.x + 1][c.y];
                    nc = new Cell(c.x + 1, c.y, c.value);
                }
                pq.offer(nc);
                visited[c.x + 1][c.y] = 1;
            }
            
            if (c.y - 1 >= 0 && visited[c.x][c.y - 1] != 1) {
                Cell nc = null;
                if (heightMap[c.x][c.y - 1] >= c.value) {
                    nc = new Cell(c.x, c.y - 1, heightMap[c.x][c.y - 1]);
                } else {
                    count += c.value - heightMap[c.x][c.y - 1];
                    nc = new Cell(c.x, c.y - 1, c.value);
                }
                pq.offer(nc);
                visited[c.x][c.y - 1] = 1;
            }
            
            if (c.y + 1 < n && visited[c.x][c.y + 1] != 1) {
                Cell nc = null;
                if (heightMap[c.x][c.y + 1] >= c.value) {
                    nc = new Cell(c.x, c.y + 1, heightMap[c.x][c.y + 1]);
                } else {
                    count += c.value - heightMap[c.x][c.y + 1];
                    nc = new Cell(c.x, c.y + 1, c.value);
                }
                pq.offer(nc);
                visited[c.x][c.y + 1] = 1;
            }
        }
        return count;
    }
    class Cell {
        int x;
        int y;
        int value;
        Cell(int x, int y, int value) {
            this.x = x;
            this.y = y;
            this.value = value;
        }
    }
    class CellComparator implements Comparator<Cell> {
        public int compare(Cell a, Cell b) {
            return a.value - b.value;
        }
    }
}

然后对照了一下人家的代码。。。又高下立现了。。。= =不过我没用过这个技巧情有可原嘛,以后就会了哈哈哈

改良后的版本:

public class Solution {
    public int trapRainWater(int[][] heightMap) {
        if (heightMap == null || heightMap.length == 0) {
            return 0;
        }
        int m = heightMap.length;
        int n = heightMap[0].length;
        int[][] visited = new int[m][n];
        int count = 0;
        PriorityQueue<Cell> pq = new PriorityQueue<>(new CellComparator());
        for (int i = 0; i < m; i++) {
            pq.offer(new Cell(i, 0, heightMap[i][0]));
            pq.offer(new Cell(i, n - 1, heightMap[i][n - 1]));
            visited[i][0] = 1;
            visited[i][n - 1] = 1;
        }
        for (int i = 0; i < n; i++) {
            pq.offer(new Cell(0, i, heightMap[0][i]));
            pq.offer(new Cell(m - 1, i, heightMap[m - 1][i]));
            visited[0][i] = 1;
            visited[m - 1][i] = 1;
        }
        int[][] nei = new int[][]{{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
        while (!pq.isEmpty()) {
            Cell c = pq.poll();
            for (int[] cor : nei) {
                int row = c.x + cor[0];
                int col = c.y + cor[1];
                if (row >=0 && row < m && col >= 0 && col < n && visited[row][col] != 1) {
                    pq.offer(new Cell(row, col, Math.max(heightMap[row][col], c.value)));
                    count += Math.max(0, c.value - heightMap[row][col]);
                    visited[row][col] = 1;
                }
            }
        }
        return count;
    }
    class Cell {
        int x;
        int y;
        int value;
        Cell(int x, int y, int value) {
            this.x = x;
            this.y = y;
            this.value = value;
        }
    }
    class CellComparator implements Comparator<Cell> {
        public int compare(Cell a, Cell b) {
            return a.value - b.value;
        }
    }
}

 

 
posted @ 2017-02-07 09:14  璨璨要好好学习  阅读(133)  评论(0编辑  收藏  举报