leetcode $42 in cpp

Code: (This method is not the best one. There are other methods using two pointers)

Key: a bar could be a left bound if it is no less than its right. A bar could be a right bound if it is no less than its left. 

class Solution {
public:
    int trap(vector<int>& height) {
        if(height.empty()) return 0;
        return find(height,0, height.size() - 1);
    }
    int find(vector<int> height,int left, int right){
        if(left >=right - 1) return 0;
        
        //find the left bound and the next closest right bound
        int left_bound = -1;//next left bound that could hold the water
        int right_bound = -1;//next closest right bound that could form a trap with left_bound
        
        for(int i = left; i < height.size(); i ++){//find the left bound that could hold water
            //two cases that it could not be a left bound:
            //1. if height < 0
            //2. if its right is no less than it
            if(height[i] <= 0 || ( i + 1 < height.size() && height[i + 1] >= height[i])) continue;
            left_bound = i;
            break; 
        }
        if(left_bound == -1 || left_bound >= height.size() - 2) return 0;
        
        int right_bound_height = -1;
        find the next closest right bound that could hold water: 
        //during the iterations we need to find:
        //1. temporary right bound candidates that could trap water with the left bound(rule: it is no
        //   less than its right)
        //2. the true right bound which is the highest bound among the right bound candidates(The  
        //   height of the true right bound among the candidates could be no less than or less than 
        //   the height of the left bound)
        //   Briefly, if we find a right bound with height > height of leftbound, we immediately stop
        //   if we could not find a right bound with height > height of leftbound, we choose the 
        //   tallst right bound among the right bound candidates found in 1. 
        for(int i = left_bound + 1; i <= right; i++){
            //three cases that it could not be a right bound of a trap:
            //1. if its height is <= 0
            //2. if its left is no less than it
            //3. if it is shorter than the current hightest right bound
            if(height[i] <=0 || (i - 1 >= 0 && height[i-1] >=height[i]) || right_bound_height > height[i]) continue;
            right_bound = i;
            right_bound_height = height[i];
            if(right_bound_height >= height[left_bound]) break;//once we find a right bound taller 
                                                    //than the left bound, we terminate the loops.
        }
        if(right_bound == -1 || right_bound <= left_bound + 1) return 0;//cannot find right bound
        //calculate the water trapped
        int res = right_bound - left_bound - 1;
        int min_height = height[right_bound]>height[left_bound]?height[left_bound]:height[right_bound];
        res*= min_height;
        //minus the volumes of barriers in the trap
        for(int i = left_bound + 1; i < right_bound; i ++){
            res -= height[i] > min_height?min_height:height[i];
        }
        //calculate the next pair of left bound and right bound.
        return res + find(height, right_bound, right);
    }
};


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值