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

图片描述

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

思路
对于每一个bar来说,能装水的容量取决于左右两侧bar的最大值。一个bar的最终高度 = MIN (Max_left_height, Max_right_height). 容器高度由左右边界中较小的一个决定。
brute force 思路: 扫描两次,一次从左向右,记录对于每一个bar来说其左侧的bar的最大高度left[i],一次从右向左,记录每一个bar右侧bar的最大高度right[i]。第三次扫描,则对于每一个bar,计算(1)左侧最大height和当前bar的height的差值(left[i] - heights[i]) (2)右侧最大height和当前bar的height的差值(right[i] - heights[i]),取(1),(2)中结果小的那个作为当前bar的蓄水量。最终求和得到总蓄水量。

Two Pointers
对撞指针问题, 根据左右两边中较矮的柱子确定当前的柱子的最终高度。 两边最大灌水量分别等于 分别 += 当前最大高度 - heights[i]。

public class Solution {
    /**
     * @param heights: an array of integers
     * @return: a integer
     */
    public int trapRainWater(int[] heights) {
        // write your code here
        if (heights == null || heights.length == 0){
            return 0;
        }
        int left = 0, right = heights.length-1;
        if (left >= right){
            return 0;
        }
        //对撞型指针问题, 左右两边更低的那根柱子决定了能灌水多少--> 比较左右两根柱子, 根据两者高低靠近, 过程中更新左边和右边的最大值(最大高度)
        //两边最大灌水量分别 += 当前最大高度 - heights[i] 
        //两指针未相遇时, leftH(左边最大高度) - heights[left]; right
        int leftHeight = heights[0];
        int rightHeight = heights[heights.length -1];
        int res = 0;
        
        while (left < right){
            if (heights[left] < heights[right]){
                left++;
                if (heights[left] < leftHeight){
                    res += leftHeight - heights[left];
                }
                else{
                    leftHeight = heights[left];
                }
            }else{
                right--;
                if (heights[right] < rightHeight){
                    res += rightHeight - heights[right];
                }else{
                    rightHeight = heights[right];
                }
            }
        }
        
        return res;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值