(算法)Trapping Rain Water II

题目:

Given n * m non-negative integers representing an elevation map 2d where the area of each cell is 1 * 1, compute how much water it is able to trap after raining.

思路:

这道题是前面一道题的一个延伸,http://www.cnblogs.com/AndyJee/p/4821590.html

前面的给出是一维数组,而这里提供的是二维数组,形象地理解,就是提供了一个立体三维得柱形容器,求该容器所能容纳的最大体积。

由于水是往低处流的, 所以对于这一类trapping water问题,我们只用从最外层开始往内接雨水就可以。

首先从矩阵的最外层中找到最小的柱子,可以通过堆来实现,当堆不为空的情况下,每次弹出的都是高度最小的柱子,这时候从该柱子出发,遍历其周边的四个方向(BSF)的柱子,如果某个柱子未到达或超出边界且尚未被访问,则将该柱子加入堆中,如果该柱子的高度比当前柱子高度小,则更新该柱子的高度,同时记录此处所容纳的水,直至堆为空。

代码:

#include<iostream>
#include<vector>
#include<stdlib.h>
#include<queue>

using namespace std;

struct cell{
    int x;
    int y;
    int h;
    cell(int xx,int yy,int hh):x(xx),y(yy),h(hh){};
    bool operator<(const cell &c)const{
        return h>c.h;
    }
};

/*
bool operator<(const cell &a,const cell &b){
    return a.h>b.h;
}
*/

int trapRainWater(const vector<vector<int> > &heights){
    int m=heights.size();
    int n=heights[0].size();
    vector<vector<int> > visited(m,vector<int>(n,0)); 

    int dx[]={1,-1,0,0};
    int dy[]={0,0,1,-1};

    priority_queue<cell> pq;
    for(int i=0;i<n;i++){
        pq.push(cell(0,i,heights[0][i]));
        pq.push(cell(m-1,i,heights[m-1][i]));
        visited[0][i]=1;
        visited[m-1][i]=1;
    }

    for(int i=0;i<m;i++){
        pq.push(cell(i,0,heights[i][0]));
        pq.push(cell(i,n-1,heights[i][n-1]));
        visited[i][0]=1;
        visited[i][n-1]=1;
    }

    int ans=0;
    while(!pq.empty()){
        cell c=pq.top();
        pq.pop();

        for(int i=0;i<4;i++){
            for(int j=0;j<4;j++){
                int nextx=c.x+dx[i];
                int nexty=c.y+dy[i];
                if(nextx>=0 && nextx<m && nexty>=0 && nexty<n && visited[nextx][nexty]==0){
                    visited[nextx][nexty]=1;
                    int h=max(c.h,heights[nextx][nexty]);
                    pq.push(cell(nextx,nexty,h));
                    ans+=max(0,c.h-heights[nextx][nexty]);
                }
            }
        }
    }
    return ans;
}

int main(){
    vector<vector<int> > heights={
        {12,13,0,12},
        {13,4,13,12},
        {13,8,10,12},
        {12,13,12,12},
        {13,13,13,13}
    };

    cout << trapRainWater(heights) <<endl; // ans=14
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值