1. 程式人生 > >LeetCode42. 接雨水

LeetCode42. 接雨水

題目

給定 n 個非負整數表示每個寬度為 1 的柱子的高度圖,計算按此排列的柱子,下雨之後能接多少雨水。

上面是由陣列 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度圖,在這種情況下,可以接 6 個單位的雨水(藍色部分表示雨水)。 感謝 Marcos 貢獻此圖。

示例:

輸入: [0,1,0,2,1,0,1,3,2,1,2,1]
輸出: 6

分析

1.自己一開始的想法:把上圖分為一層一層,每一層的高度為1,用棧分別計算每層的凹進去格子個數,加在一起,哈哈哈哈哈,資料量小還可以用,資料量一大,就超時了,時間複雜度O(n^2)。

2.還是看了解題報告,只要遍歷三次,就可以得出結果,哇塞好神奇。

其實這個題只要能知道第x個柱子的 左邊最高柱子 和 右邊最高柱子 中比較矮的一個,然後用較矮柱子的高度減去當前第x個柱子的高度,就是當前x柱子可以接住的雨水量。

說的有點兒繞,寫成表示式就是: x柱子接住雨水量 =  min( left_max, right_max) - height[x]

程式碼

class Solution {
    public int trap(int[] height) {
        int len = height.length;
        if (len == 0) return 0;
        int[] left_max = new int[len];
        int[] right_max = new int[len];

        int max = height[0];
        for (int i = 0; i < len; i++) {
            if (max > height[i]){
                left_max[i] = max;
            }else{
                left_max[i] = height[i];
                max = height[i];
            }
        }

        max = height[len-1];
        for (int i = len-2; i >= 0; i--) {
            if (max > height[i]){
                right_max[i] = max;
            }else{
                right_max[i] = height[i];
                max = height[i];
            }
        }

        int sum = 0;
        for (int i = 1; i < len-1; i++) {
            sum += Math.min(left_max[i],right_max[i]) - height[i];
        }

        return sum;
    }
}