1. 程式人生 > >42. 接雨水(Trapping rain water)

42. 接雨水(Trapping rain water)

題目描述

在這裡插入圖片描述LeetCode.cn地址:https://leetcode-cn.com/problems/trapping-rain-water/
LeetCode地址:https://leetcode.com/problems/trapping-rain-water/

思路

首先求出最大值的索引,設為i1,然後向左遍歷,求出左邊範圍內的最大值,記索引為i2,以i2和i1對應值之間為容器,雨水可以儲存在此中,多餘的雨水會流向左右的下方。
記容積為height[i2] * (i1-i2),減去中間凸出的值,即為雨水的量。然後記i1=i2,再繼續向左遍歷。直到i1=0為止。
同理向右遍歷。

模型解釋

在這裡插入圖片描述如上圖所示,把最大值的索引記為i1,左邊範圍內的最大值索引為i2,可見,i2~i1之間儲存了雨水。
那麼這一部分雨水是多少呢?

讓我們把圖更精確一點:
在這裡插入圖片描述雨水的體積就等於 height[i2]*(i1-i2)減去i2和i1之間黑色塊的體積。
這一段的程式碼:

int i2 = max(height, 0, i1);
int a = height[i1], b = height[i2];
int tmp = b*(i1-i2);
for(int j = i2;j<i1;j++){
	tmp -= height[j];
}
res += tmp;

之後令i1等於i2,向左重複以上步驟。

當然右邊部分的也處理相同。

程式碼

class Solution {
    public int trap(int[] height) {
        int res = 0;
        int left = 0, right = height.length;
        
        if(height == null || height.length==0||height.length==1)    return res;
        
        int i1 = max(height, 0, right);
        
        while(i1>0){
            int i2 = max(height, 0, i1);
            int a = height[i1], b = height[i2];
            int tmp = b*(i1-i2);
            for(int j = i2;j<i1;j++){
                tmp -= height[j];
            }
            res += tmp;
            i1 = i2;
        }
        
        i1 = max(height, 0, right);
        while(i1<height.length-1){
            int i2 = max(height, i1+1, right);
            int a = height[i1], b = height[i2];
            int tmp = b*(i2-i1);
            for(int j = i2;j>i1;j--){
                tmp -= height[j];
            }
            res+=tmp;
            i1 = i2;
        }
        return res;
    }
    
    public static int max(int[] nums, int l, int r){
        int tmp = nums[l];
        int res = l;
        for(int i=l;i<r;i++){
            if(nums[i]>tmp){
                tmp = nums[i];
                res = i;
            }
        }
        return res;
    }
}

更多LeetCode題解在 https://github.com/FuGaZn/LeetCode
歡迎過來給個Star~
您的肯定是我更新的動力。