LeetCode 42. 接雨水

解法一

求每一列的水,我们只需要关注当前列,以及左边最高的墙,右边最高的墙就够了。时间复杂度O(n^2),超时

class Solution {
public:
    int trap(vector<int>& height) {
        int ans = 0;
        for (int i = 1;i < height.size()-1;i++) {
            int max_left = 0;
            for (int j = i - 1;j >= 0;j--) {
                max_left = max(max_left,height[j]);
            }
            int max_right = 0;
            for (int j = i+1;j < height.size();j++) {
                max_right = max(max_right,height[j]);
            }
            int min_num = min(max_left,max_right);

            if (min_num > height[i]) {
                ans += (min_num-height[i]);
            }
        }
        return ans;
    }
};

解法二

动态规划

首先用两个数组,max_left [i]代表第 i 列左边最高的墙的高度,max_right[i] 代表第 i 列右边最高的墙的高度。(一定要注意下,第 i 列左(右)边最高的墙,是不包括自身的,和力扣上边的讲的有些不同)

class Solution {
public:
    int left[20010];
    int right[20010];
    int trap(vector<int>& height) {
        int n = height.size();
        int ans = 0;
        left[0] = height[0];
        for (int i = 1;i < n;i++) {
            left[i] = max(height[i-1],left[i-1]);
        }
        right[n-1] = height[n-1];
        for (int i = n-2;i >= 0;i--) {
            right[i] = max(right[i+1],height[i+1]);
        }
        for (int i = 1;i < n-1;i++) {
            if (height[i] < min(left[i],right[i])) {
                ans += min(left[i],right[i]) - height[i];
            }
        }
        return ans;
    }
};

解法三

双指针

max_left [ i ]max_right [ i ] 数组中的元素我们其实只用一次,然后就再也不会用到了。所以我们可以不用数组,只用一个元素就行了。我们先改造下 max_left

class Solution {
public:
    int trap(vector<int>& height) {
        int ans = 0;
        int left = 0;
        int right = 0;
        int l = 1,r = height.size()-2;
        for (int i = 1;i < height.size() - 1;i++) {
            if (height[l-1] < height[r+1]) {
                left = max(left,height[l-1]);
                if (left > height[l]) {
                    ans += (left-height[l]);
                }
                l++;
            }else {
                right = max(right,height[r+1]);
                if (right > height[r]) {
                    ans += right-height[r];
                }
                r--;
            }
        }
        return ans;
    }
};

未完待续...