LeetCode 407.接雨水Ⅱ

给你一个 m x n 的矩阵,其中的值均为非负整数,代表二维高度图每个单元的高度,请计算图中形状最多能接多少体积的雨水。

示例:

给出如下 3x6 的高度图:
[
[1,4,3,1,3,2],
[3,2,1,3,2,4],
[2,3,3,2,3,1]
]

返回 4 。

用最小堆维护从外向内的最小元素
每次从最小的元素向四周搜索 比它大直接加入堆 比它小即将总接水量加上它们的差值 然后将新元素入堆(新元素入堆的高为搜索到它的元素的高 可以接到最多的水)
所有搜索过的元素为避免重复搜索 用一个矩阵来记录信息

class Solution {
    class pos{
        int x;
        int y;
        int h;
        pos(int x, int y, int h){
            this.x = x;
            this.y = y;
            this.h = h;
        }
    }
    public int trapRainWater(int[][] heightMap) {
        int n = heightMap.length;
        int m = heightMap[0].length;
        if(heightMap == null || n == 0 || m == 0)
            return 0;
        int[][] visited = new int[n][m];
        Queue<pos> minheap = new PriorityQueue<>(new Comparator<pos>(){
            public int compare(pos a, pos b){
                return a.h - b.h;
            }
        });
        for(int i = 0; i < n; i++){
            minheap.offer(new pos(i, 0, heightMap[i][0]));
            minheap.offer(new pos(i, m - 1, heightMap[i][m-1]));
            visited[i][0] = 1;
            visited[i][m-1] = 1;
        }
        for(int j = 0; j < m; j++){
            minheap.offer(new pos(0, j, heightMap[0][j]));
            minheap.offer(new pos(n - 1, j, heightMap[n-1][j]));
            visited[0][j] = 1;
            visited[n-1][j] = 1;
        }
        int[] cx = {0, 1, 0, -1};
        int[] cy = {1, 0, -1, 0};
        int ret = 0;
        while(!minheap.isEmpty()){
            pos p = minheap.poll();
            for(int i = 0; i < 4; i++){
                int newx = p.x + cx[i];
                int newy = p.y + cy[i];
                if(newx < 0 || newy < 0 || newx >= n || newy >= m || visited[newx][newy] == 1)
                    continue;
                if(heightMap[newx][newy] < p.h){
                    ret += p.h - heightMap[newx][newy];
                    minheap.offer(new pos(newx, newy, p.h));
                }
                else{
                    minheap.offer(new pos(newx, newy, heightMap[newx][newy]));
                }
                visited[newx][newy] = 1;
            }
        }
        return ret;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值