Leetcode42 Trapping Rain Water

看到这道题的第一想法是使用一个水平线变量level,每次将level提高1直到max{height[i]}结束循环,代码如下:

int max = -1, left = -1, capa = 0;
for(int i=0; i<height.size(); i++)
    max = max<height[i]? height[i]:max;
//每次外循环结束得到高度在level以下所存储的水量
for(int level=1,j; level<=max; level++){
    j = 0;
    while(j<height.size()&&height[j]<level)//找到第一个大于等于level高度的点,作为水槽左端
        j++;
    while(height[j]>=level){
        left = j;
        while(j<height.size()&&height[j]<level)//找到水槽右端
            j++;
        if(j==height.size())//到达数组末尾则结束循环
            break;
        capa += j-left-1;//增加水槽装的水的容量
    }
}
                

这个思路是:每次先找到高度大于等于level的一边,然后求高度低于level的部分也就是求高度为1的水槽的容量。

然而,很明显,这里时间复杂度为O(n*max(height)),时间性能很差。

不难发现,随着level的增大,高度大于level的点变得很少,也就是说,时间被浪费在了遍历那些低于level 的元素上,因此思路便转向如何避免重复对这些无效元素的遍历。实际上,若某个点高度为height[i],那么对任意k>i,height[i]和height[k]都可以形成一个水槽。关键在于若height[i]<=height[k],则height[i]就无法与height[j](j>k)形成水槽,因此有了以下算法。

int trap(vector<int>& height) {
        int capa = 0, size = height.size(), ll = 0;
        stack<int> s;
        for(int i=0; i<size; i++){
            ll = 0;
            while(s.size()>0&&height[s.top()]<=height[i]){           
                capa += (height[s.top()]-ll)*(i-s.top()-1);
                ll = height[s.top()];
                s.pop();
            }
            if(s.size()>0){
                capa += (height[i]-ll)*(i-s.top()-1);
            }         
            s.push(i);
        }
        return capa;     
    }

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值