LeetCode | 42. Trapping Rain Water

Given n non-negative integers representing an elevation map where the width of each bar is 1, compute how much water it is able to trap after raining.

For example, 
Given [0,1,0,2,1,0,1,3,2,1,2,1], return 6.

这里写图片描述

思路:模拟算法,对于每个it,向右查找,分两种情况:
1、右边找到一个不比他矮的,那就把它作为右边界,因为再向右产生的水坑就和it没关系了
2、找不到不必it矮的,就找一个其中最高的且第一次出现的,作为右边界。
然后计算右边界和it之间产生的水坑的面积

//13 ms
class Solution {
public:
    int trap(vector<int>& height)
    {
        int len = height.size();
        int res = 0;
        int it = 0, max_index = 0, mmax = 0;

        while(it < len)
        {
            max_index = it;
            mmax = 0;
            for(int i=it+1;i<len;i++)
            {
                if(height[i] >= height[it])//比他高了,后面的水坑不由it决定了
                {
                    max_index = i; break;
                }
                if(height[i] > mmax)//找到后面第一个最高的那个,比如50202,就是第三个
                {
                    mmax = height[i];
                    max_index = i;
                }
            }
            int delta = min(height[it],height[max_index]);
            for(int j=it;j<max_index;j++)
            {
                if(height[j] < delta)
                    res += (delta-height[j]);
            }
            if(max_index == it)
                it++;
            else
                it = max_index;
        }

        return res;
    }
};

另一个思路,solution中提供的O(n)算法,实际运行时效果反而不是很理想,16 ms

class Solution {
public:
    int trap(vector<int>& height)
    {
        int n = height.size();
        int left=0; int right=n-1;
        int res=0;
        int maxleft=0, maxright=0;

        while(left<=right)
        {
            if(height[left]<=height[right])
            {
                if(height[left]>=maxleft) 
                    maxleft=height[left];
                else 
                    res+=maxleft-height[left];
                left++;
            }
            else
            {
                if(height[right]>=maxright)
                    maxright= height[right];
                else 
                    res+=maxright-height[right];
                right--;
            }
        }
        return res;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值