【LeetCode 算法】Trapping Rain Water 接雨水-数组处理

文章目录

  • Trapping Rain Water 接雨水
    • 问题描述:
    • 分析
    • 代码
    • Tag

Trapping Rain Water 接雨水

问题描述:

给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。

n = = h e i g h t . l e n g t h 1 < = n < = 2 ∗ 1 0 4 0 < = h e i g h t [ i ] < = 1 0 5 n == height.length\\ 1 <= n <= 2 * 10^4\\ 0 <= height[i] <= 10^5 n==height.length1<=n<=21040<=height[i]<=105

分析

对于一个二维柱面来说,某个位置x是否能接到雨水,必然是其左右2侧要高于 h x h_x hx,同时由于木桶效应,可以接到雨水的高度取决于2侧最低的柱子高度

如果是暴力,就是固定一个位置 i,然后向2侧找到最高的柱子 l e f t , r i g h t left,right leftright,用min表示2侧最低, m i n = m i n ( l e f t , r i g h t ) . min = min(left,right). min=min(leftright).
如果 m i n > h i min>h_i min>hi,说明可以接到雨水 m i n − h i min-h_i minhi.否则位置 i i i的2侧没有高于它的柱子,无法接水

暴力的一次时间复杂度就是 O ( N ) O(N) O(N),数组的长度为 N N N,整体的时间复杂度 O ( N 2 ) . O(N^2). O(N2).

以当前的数据规模,必然TLE。

所以需要加速一下,可以使用一个数组,在遍历的过程中,记录下每个位置i左侧的最大柱子高度,在 O ( N ) O(N) O(N)的时间复杂度,就可以得到每个位置的 l e f t left left柱子信息。

同样再从右到左的一次处理,就可以得到每个位置的 r i g h t right right侧信息,并且进行计算可以得到每个位置上的雨水高度。

代码

public int trap(int[] height) {
        int n = height.length;
        int[] left = new int[n];
        int max = 0;
        for(int i =0;i<n;i++){
            if(height[i]<max){
                left[i] = max;
            }
            else{
                left[i] = height[i];
            }
            max = Math.max(max,height[i]);
        } 
        int ans =0;
        max =0;
        for(int i =n-1;i>=0;i--){
            int h = Math.min(left[i],max);
            ans += Math.max(0,h - height[i]);
            max = Math.max(max,height[i]);
        }
        return ans;
    }

时间复杂度 O ( N ) O(N) O(N)

空间复杂度 O ( N ) O(N) O(N)

Tag

Array

你可能感兴趣的:(数据结构与算法,算法,leetcode)