LintCode 接雨水

題目

給出 n 個非負整數,代表一張X軸上每個區域寬度為 1 的海拔圖, 計算這個海拔圖最多能接住多少(面積)雨水。

Paste_Image.png

樣例
如上圖所示,海拔分別為 [0,1,0,2,1,0,1,3,2,1,2,1], 返回 6.

分析

有三種方法思路可以解決

方法一:

首先從左遍歷一遍,找到已左邊為基準的高度
再從右邊遍歷一遍找到以右邊為基準的高度,
要能夠接住水,就要求左右兩邊,最小的一邊的高度應該比中間的都要大,能接住的水的面積就是這些差值。
看代碼

public class Solution {
    /**
     * @param heights: an array of integers
     * @return: a integer
     */
    public int trapRainWater(int[] A) {
        if(A == null || A.length < 3)
            return 0;
        
        int localMax = A[0];
        int[] left = new int[A.length];
        int[] right = new int[A.length];
        
        for(int i=0;i<A.length;i++) {
            if(A[i] <= localMax)
                left[i] = localMax;
            else {
                localMax = A[i];
                left[i] = localMax;
            }
        }
        
        localMax = A[A.length-1];
        for(int i=A.length-1;i>-1;i--) {
            if(A[i] <= localMax)
                right[i] = localMax;
            else {
                localMax = A[i];
                right[i] = localMax;
            }
        }
        
        int area = 0;
        for(int i=0;i<A.length;i++) {
            area += Math.min(left[i], right[i]) - A[i];
        }
        
        return area;
    }
}

方法二

首先遍歷一遍找到最高點,然后從左右兩邊分別向最高點進發

public class Solution {
    /**
     * @param heights: an array of integers
     * @return: a integer
     */
    public int trapRainWater(int[] heights) {
        if(heights.length <= 2) return 0;
        int max = -1, maxInd = 0;
        int i = 0;
        for(; i < heights.length; ++i){
            if(heights[i] > max){
                max = heights[i];
                maxInd = i;
            }
        }
        int area = 0, root = heights[0];
        for(i = 0; i < maxInd; ++i){
            if(root < heights[i]) root = heights[i];
            else area += (root - heights[i]);
        }
        for(i = heights.length-1, root = heights[heights.length-1]; i > maxInd; --i){
            if(root < heights[i]) root = heights[i];
            else area += (root - heights[i]);
        }
        return area;
    }
}

方法三

左右兩個指針,一頭一尾開始遍歷,首先找到自己這一邊的局部最高點,只要比最高點小就可以裝水

public class Solution {
    /**
     * @param heights: an array of integers
     * @return: a integer
     */
    public int trapRainWater(int[] A) {
        if(A == null || A.length < 3)
            return 0;
        
        //兩根指針一頭一尾向中間進發
        int left = 0;
        int right = A.length-1;
        //兩個變量存儲左右兩邊的局部最大高度
        int leftMax = 0;
        int rightMax = 0;
        
        int area = 0;
        
        while(left <= right) {
            leftMax = Math.max(leftMax, A[left]);
            rightMax = Math.max(rightMax, A[right]);
            
            //小的那邊可以存水
            if(leftMax <= rightMax) {
                if(leftMax > A[left])
                    area += leftMax - A[left];
                left++;
            }
            else {
                if(rightMax > A[right])
                    area += rightMax - A[right];
                right--;
            }
        }
        
        return area;
    }
}
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 背景 一年多以前我在知乎上答了有關LeetCode的問題, 分享了一些自己做題目的經驗。 張土汪:刷leetcod...
    土汪閱讀 12,771評論 0 33
  • Spring Cloud為開發人員提供了快速構建分布式系統中一些常見模式的工具(例如配置管理,服務發現,斷路器,智...
    卡卡羅2017閱讀 134,948評論 18 139
  • 有人說20-30歲是我們的迷茫期,有人說30幾歲你還在迷茫是不是沒救了,更有人說如果重來一次我不要那么拼命工作,要...
    Sunny_Zhu閱讀 227評論 0 0
  • 心里有種俗稱長草的感覺 有些浮躁 卻又不是那么浮躁 購物已經不能滿足自己 淘寶京東翻了好多遍 卻還是急切的想做些什...
    易夕與長勤閱讀 176評論 0 0
  • 夢回學生時代,語文課堂,老師正在講解練習題。連續上了兩堂課,在焦急的等待下課鈴聲,在掙扎的一會,還沒有到下課時間...
    瑞香Provence閱讀 132評論 0 1