Bootstrap

【Leetcode】--- 接雨水

题目传送门

 

方法一: 前缀和+后缀和

算法原理

需要两个数组。

第一个数组存储最左边到第 i 个位置的最大高度(前缀最大值)

第二个数组存储最右边到第 i 个位置的最大高度(后缀最大值)

最终第 i 个位置的

接水量 = min(第 i 位置的前缀最大值,第 i 位置的后缀最大值)- 第 i 位置的高度

例如上示例:

height =         0,1,0,2,1,0,1,3,2,1,2,1

前缀最大值 = 0,1,1,2,2,2,2,3,3,3,3,3

后缀最大值 = 3,3,3,3,3,3,3,3,2,2,2,1

最终求得       0,0,1,0,1,2,1,0,0,1,0,0 累加得6

代码:

class Solution {
    public int trap(int[] height) {
        int n = height.length;
        int[] f = new int[n];
        int[] g = new int[n];
        f[0] = height[0];
        g[n-1] = height[n-1];
        int sum = 0;

        for(int i = 1; i < n; i++){
            f[i] = Math.max(height[i],f[i-1]);  
        }
        for(int i = n-2; i >= 0; i--){
            g[i] = Math.max(height[i],g[i+1]);  
        }

        for(int i = 0; i < n; i++){
            sum += Math.min(f[i],g[i]) - height[i];
        }
        return sum;
    }
}

复杂度分析

时间复杂度:O(n)

空间复杂度 :O(n)

解法二:双指针(法一的优化)

算法原理

如果左边前缀最大值比右边前缀最大值小,那么接水量就是左边前缀最大值 - 当前高度

如果左边前缀最大值比右边前缀最大值大,那么接水量就是右边前缀最大值 - 当前高度

代码: 

class Solution {
    public int trap(int[] height) {
        int n = height.length;
        int left = 0;
        int right = n -1;
        int left_MAX = 0,right_MAX = 0;
        int sum = 0;
        
        while(left < right){
            left_MAX = Math.max(height[left],left_MAX);
            right_MAX = Math.max(height[right],right_MAX);
            if(left_MAX < right_MAX){
                sum += left_MAX - height[left];
                left++;
            }else{
                sum += right_MAX - height[right];
                right--;
            }        
        }
        return sum;
    }
}

 

复杂度分析

 时间复杂度:O(n)

空间复杂度 :O(1)

 

 

 

 

;