leetcode_42. Trapping Rain Water

本文介绍了一种计算二维地形中雨水捕捉量的算法。首先通过复杂的递归方法实现了解决方案,随后给出了更为简洁高效的双指针法。递归方法中利用了结构体存储高度和索引,并通过排序和递归调用计算水容量。而双指针法则从两侧向中间逼近,避免了递归的繁琐。

这种题目的关键就是找到内在逻辑,然后递推下去。我的思路是,先找到最高的点,再依次向左右找次高的点,计算水容量,然后不断递归找次高点,直到边界位置。虽然实现了,结果十分繁琐!!

struct Rank
    {
        int height;
        int rank1;
    };
    static bool cmp(Rank a,Rank b)//不加static好像会报错
    {
        return a.height>b.height;
    }
    int cal(vector<int>& H,int a,int b)
    {
        int sum=0,temp=H[a]<H[b]? H[a]:H[b];
        for(int i=a+1;i<=b-1;i++) //曾经此处少了等于号,调试半天
            sum+=temp-H[i];
        return sum;
    }
    int seek1(vector<int>& H,vector<Rank> &R,int a,int b,int sum,int c)//传入向量必须+&,向左寻找次高点
    {
        if(a==0) {sum+=cal(H,a,b);return sum;}
        else{
            sum+=cal(H,a,b);
            int i;
            for(i=c;i<R.size();i++)
            {
                if(R[i].rank1<a) break;
            }
            return seek1(H,R,R[i].rank1,a,sum,i+1);//此处竟然忘记return
        }
    }
    int seek2(vector<int>& H,vector<Rank> &R,int a,int b,int sum,int c)
    {
        if(b==H.size()-1) return sum+cal(H,a,b);
        else{
            sum+=cal(H,a,b);
            int i;
            for(i=c;i<R.size();i++)
            {
                if(R[i].rank1>b) break;
            }
            return seek2(H,R,b,R[i].rank1,sum,i+1);
        }
    }
    int trap(vector<int>& H) {
        vector<Rank> R;
    if(H.size()==0) return 0;
        for(int i=0;i<H.size();i++)
        {
            Rank temp;
            temp.height=H[i];
            temp.rank1=i;
            R.push_back(temp);
        }
        sort(R.begin(),R.end(),cmp);
        int sum=0;
        sum+=seek1(H,R,R[0].rank1,R[0].rank1,0,1);
        sum+=seek2(H,R,R[0].rank1,R[0].rank1,0,1);
        return sum;
    }

然而,简单的思路恰好与我相反,从两边出发(two point),到中间汇合,无需递归,为啥我就没反过来想想呢??

int trap(int A[], int n) {
        int left=0; int right=n-1;
        int res=0;
        int maxleft=0, maxright=0;
        while(left<=right){
            if(A[left]<=A[right]){
                if(A[left]>=maxleft) maxleft=A[left];
                else res+=maxleft-A[left];
                left++;
            }
            else{
                if(A[right]>=maxright) maxright= A[right];
                else res+=maxright-A[right];
                right--;
            }
        }
        return res;
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值