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

圖片描述

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的蓄水量。最終求和獲得總蓄水量。code

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;
    }
}
相關文章
相關標籤/搜索