每天一道算法题14

如果给你一个二维数组,每一个值表示这一块地形的高度,求整块地形能装下多少水。

解答:这个问题用小根堆解决,先把最外围的一圈入小根堆,然后弹出最小的,将max赋值为它,然后找到他上下左右的点,入小根堆,如果当时比max小,则蓄水量为max - arr[i],如果小于0,则说明不能蓄水,继续弹出小根堆,更新max,如果>0,则继续将该上下左右入堆。

public static class Node {
    public int value;
    public int row;
    public int col;

    public Node(int v, int r, int c) {
        this.value = v;
        this.row = r;
        this.col = c;
    }
}

public static class NodeComparator implements Comparator {
    @Override
    public int compare(Node o1, Node o2) {
        return o1.value - o2.value;
    }
}

public static int trapRainWater(int[][] heightMap) {
    if (heightMap == null || heightMap.length == 0 || heightMap[0] == null || heightMap[0].length == 0) {
        return 0;
    }
    int N = heightMap.length;
    int M = heightMap[0].length;

    //isEnter[i][j] = true 之前进过
    //isEnter[i][j] = false 之前没进过
    boolean[][] isEnter = new boolean[N][M];

    //小跟堆
    PriorityQueue heap = new PriorityQueue<>(new NodeComparator());

    for (int col = 0; col < M-1; col++) {
        isEnter[0][col] = true;
        heap.add(new Node(heightMap[0][col],0,col));
    }

    for (int row = 0; row < N -1; row++) {
        isEnter[row][0] = true;
        heap.add(new Node(heightMap[row][0], row, 0));
    }

    for (int col = M - 1; col > 0; col --) {
        isEnter[N - 1][col] = true;
        heap.add(new Node(heightMap[N-1][col], N-1, col));
    }

    for (int row = N - 1; row > 0; row --) {
        isEnter[row][M-1] = true;
        heap.add(new Node(heightMap[row][M-1], row, N-1));
    }

    int water = 0; 
    int max = 0;
    while(!heap.isEmpty()) {
        Node cur = heap.poll();
        max = Math.max(max, cur.value);
        int r = cur.row;
        int c = cur.col;
        if (r > 0 && !isEnter[r-1][c]) {
            water += Math.max(0, max-heightMap[r-1][c]);
            isEnter[r-1][c] = true;
            heap.add(new Node(heightMap[r-1][c], r-1,c));
        }

        if (r < N - 1 && !isEnter[r+1][c]) {
            water += Math.max(0, max - heightMap[r+1][c]);
            isEnter[r+1][c] = true;
            heap.add(new Node(heightMap[r+1][c], r+1, c));
        }

        if (c > 0 && !isEnter[r][c-1]) {
            water += Math.max(0, max - heightMap[r][c-1]);
            isEnter[r][c-1] = true;
            heap.add(new Node(heightMap[r][c-1]));
        }

        if (c < M-1 && !isEnter[r][c+1]) {
            water += Math.max(0, max - heightMap[r][c+1]);
            isEnter[r][c+1] = true;
            heap.add(new Node(heightMap[r][c+1]));
        }
    }
    return water;
}

你可能感兴趣的:(每天一道算法题14)