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


The above elevation map is represented by array [0,1,0,2,1,0,1,3,2,1,2,1]. In this case, 6 units of rain water (blue section) are being trapped. Thanks Marcosfor contributing this image!

Example:

Input: [0,1,0,2,1,0,1,3,2,1,2,1]
Output: 6

 

思路:

一个柱能不能储水是看它的左边的最大值和右边的最大值,我们可以首先从左向右遍历找出左边的最大值,然后再从右向左遍历找出右边最大值,同时判断该柱状是否可以储水,即将该柱的值与左右两边最大值的最小值相比较,如果大于最小值,说明无法储水,小于最小值,则可以储水。

 

代码:

class Solution {
public:
    int trap(vector<int>& height) {
        if(height.size() < 2)
            return 0;
        int water = 0;
        int maxH = 0;
        vector<int> left;
        for(int i = 0; i < height.size(); i++){
            left.push_back(maxH);
            maxH = max(maxH, height[i]);
        }
        maxH = height[height.size()-1];
        for(int i = height.size() - 2; i > -1; i--){
            int shorter = min(maxH, left[i]);
            maxH = max(maxH, height[i]);
            if(shorter <= height[i])
                continue;
            water += (shorter - height[i]);   
        }
        return water;
    }
};

时间复杂度应该为O(n), 空间复杂度也为O(n),但是是经过了两轮遍历。

OJ后只在21%左右,所以一定存在更优的方案。

 

改进:

上面的方法我们遍历数组了两次,优化方法可以尝试只遍历数组一次。

链接:https://leetcode.com/problems/trapping-rain-water/discuss/127397/My-Java-Two-Pointer-Solution-with-detailed-explanation

代码:

class Solution {
public:
    int trap(vector<int>& height) {
        if(height.size() < 3)
            return 0;
        int leftW = height[0];
        int rightW = height[height.size() - 1];
        int water = 0;
        int left = 1;
        int right = height.size() - 1;
        while(left <= right){
            if(leftW <= rightW){
                water += max(leftW - height[left], 0);
                leftW = max(height[left], leftW);
                left++;
            }else{
                water += max(rightW - height[right], 0);
                rightW = max(height[right], rightW);
                right--;
            }
        }
        return water;
    }
};

 

转载于:https://www.cnblogs.com/yaoyudadudu/p/9080812.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值