力扣HOT100-接雨水

思路

首先思考,暴力解法需要怎么做?

最简单的就是,对于每个列,我们都去找它左右两边最高的列,这样我们就能根据下面的公式,计算出当前列能存储的雨水了。

这种方法的时间复杂度 :遍历每个列是O(n),对于每个列去寻找它左右两边最高的列,时间复杂度也是O(n),因此累计后就是O(n*n)。

开始进行优化。我们可以维两个数组,分别记录当前位置左边的最高列的高度和右边最高列的高度,这是我们就省去了对每个列的单独寻找。

Python版本

class Solution:
    def trap(self, height: List[int]) -> int:
        # 当前列能存储的雨水 = min(左边最高的列,右边最高的列) - 当前列的高度
        # 复杂的地方在于,如何快速获取当前列两边的最高列
        # 通过两个数组来维护
        n = len(height)
        max_left = [0 for _ in range(n)]
        max_right = [0 for _ in range(n)]
        # 存储第i列左边最高的高度
        for i in range(n):
            if i == 0:
                max_left[i] = height[i]
            else:
                max_left[i] = max(max_left[i-1],height[i])
        # 存储第i列右边最高的高度
        for i in range(n-1,-1,-1):
            if i == (n-1):
                max_right[i] = height[i]
            else:
                max_right[i] = max(max_right[i+1],height[i])
        # 获取答案
        res = 0
        for i in range(n):
            res += (min(max_left[i],max_right[i])-height[i])
        return res

Java版本

class Solution {
    public int trap(int[] height) {
        int n = height.length;
        int res = 0;
        int[] max_left = new int[n];
        int[] max_right = new int[n];
        for (int i = 0;i<n;i++){
            if (i == 0){
                max_left[i] = height[i];
            }else{
                max_left[i] = Math.max(height[i],max_left[i-1]);
            }
        }
        for (int i = n-1;i>=0;i--){
            if (i == n-1){
                max_right[i] = height[i];
            }else{
                max_right[i] = Math.max(height[i],max_right[i+1]);
            }
        }
        for (int i = 0;i<n;i++){
            res += (Math.min(max_left[i],max_right[i]) - height[i]);
        }
        return res;
    }
}

你可能感兴趣的:(力扣HOT100,leetcode,算法,java)