Leetcode #42 #407 Solution

Problem Description

  • 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.

Some Details

  • #42 is similar to this problem, which give a line with n heights as a map rather than a n*m matrix map like #407. No doubt #42 is much easier. Try it first.

Solution

    这题比较拧巴,比较simple的逻辑是从二维向三维迁移,不多提这种方法,空间想象不太行。
    我的思路是这样的。考虑木桶原理,漏水取决于当前最短板,将方阵想象成逐渐内缩的木桶边缘,首先找到外圈边缘的最短板,对于最短板邻接的格子,如果比最短板低,一定可以存水到高度与最短板一致,否则不存水,高度不变。进行过判定后邻接格子变为外圈的一部分,重新取圈中最短板,直至整个水桶都变为木桶边缘。
    取最短板的过程可以堆优化。
    #42就是二维的,不说了吧?

Code

struct heap
{
    pair<int,pair<int,int> > A[20010];
    int siz;
    heap()
    {
        siz=0;
    }
    bool empty()
    {
        if (siz) return 0; else return 1;
    }
    void up(int x)
    {
        pair<int,pair<int,int> > t;
        while (x!=1)
        {
            int fa=x/2;
            if (A[fa].first>A[x].first)
            {
                t=A[fa]; A[fa]=A[x]; A[x]=t;
                x=fa;   
            } else break;
        }
    }
    void add(int x,int y,int c)
    {
        A[++siz]=make_pair(c,make_pair(x,y));
        up(siz);
    }
    pair<int,pair<int,int> > pop()
    {
        pair<int,pair<int,int> > ans=A[1],tt;
        //for (int i=1;i<=siz;i++) cout<<A[i].first<<" "; cout<<endl;
        A[1]=A[siz--];
        if (siz!=0)
        {
            int x=1;
            while (x<=siz)
            {
                int ls=x*2,rs=x*2+1,t=x;
                if (ls<=siz && A[t].first>A[ls].first) t=ls;
                if (rs<=siz && A[t].first>A[rs].first) t=rs;
                if (t!=x)
                {
                    tt=A[t]; A[t]=A[x]; A[x]=tt; x=t;
                } else break;
            }
        }
        //for (int i=1;i<=siz;i++) cout<<A[i].first<<" "; cout<<endl;
        return ans;
    }
};

const int xx[4]={-1,0,0,1};
const int yy[4]={0,-1,1,0};
class Solution 
{
public:
    int n,m;
    int turn(int i,int j)
    {
        return i*m+j;   
    }
    int trapRainWater(vector<vector<int>>& heightMap) 
    {
        int ans=0;
        heap A;
        n=heightMap.size();
        if (n==0) return 0;
        m=heightMap[0].size();
        bool *pd=new bool[n*m+10];
        memset(pd,0,sizeof(pd));
        for (int i=0;i<n;i++)
        {
            A.add(i,0,heightMap[i][0]); pd[turn(i,0)]=true;
            A.add(i,m-1,heightMap[i][m-1]); pd[turn(i,m-1)]=true;
        }
        for (int i=1;i<m-1;i++)
        {
            A.add(0,i,heightMap[0][i]); pd[turn(0,i)]=true;
            A.add(n-1,i,heightMap[n-1][i]); pd[turn(n-1,i)]=true;
        }
        while (!A.empty())
        {
            pair<int,pair<int,int> > b=A.pop();
            int x=b.second.first,y=b.second.second,mx=b.first;
            //cout<<x<<" "<<y<<" "<<mx<<endl;
            for (int i=0;i<4;i++)
            {
                int X=x+xx[i],Y=y+yy[i];
                if (X<0 || X>n-1) continue;
                if (Y<0 || Y>m-1) continue;
                if (!pd[turn(X,Y)])
                {
                    pd[turn(X,Y)]=true;
                    if (mx>heightMap[X][Y])
                    {
                        ans+=mx-heightMap[X][Y];
                        A.add(X,Y,mx);
                    } else A.add(X,Y,heightMap[X][Y]);
                    //cout<<X<<" "<<Y<<" "<<ans<<" "<<heightMap[X][Y]<<endl;
                }
            }
        }
        return ans;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值