动态规划(接雨水)

动态规划

接雨水:https://leetcode.cn/problems/trapping-rain-water/description/
动态规划(接雨水)_第1张图片

第一步遍历标记从左到右的最大值 maxL[ ] 和从右到左的最大值 maxR[ ],第二步再从左到右(或从右到左)遍历计算雨水总量。
第二步中:遍历到 i 时,选择 maxL[i] 与 maxR[i] 中的最小者减去当前高度 height[i] ,则为当前 i 列储存雨水量。
动态规划(接雨水)_第2张图片

    public int trap(int[] height) {
        int  res = 0, n = height.length;

        int maxL[] = new int[n], maxR[] = new int[n];
        maxL[0] = height[0];
        maxR[n - 1] = height[n - 1];

        for(int i = 1; i < n; i++)
            maxL[i] = Math.max(maxL[i - 1], height[i]);

        for(int i = n - 2; i > -1; i--)
            maxR[i] = Math.max(maxR[i + 1], height[i]);

        for(int i = 0; i < n; i++)
            res += maxL[i] < maxR[i] ? maxL[i] - height[i] : maxR[i] - height[i];

        return res;
    }

简化一次:

    public int trap(int[] height) {
        int  res = 0, n = height.length;

        int maxL[] = new int[n], maxR[] = new int[n];
        maxL[0] = height[0];
        maxR[n - 1] = height[n - 1];

        for(int i = n - 2; i > -1; i--)
            maxR[i] = Math.max(maxR[i + 1], height[i]);

        for(int i = 1; i < n; i++) {
            maxL[i] = Math.max(maxL[i - 1], height[i]);
            res += maxL[i] < maxR[i] ? maxL[i] - height[i] : maxR[i] - height[i];
        }

        return res;
    }

双指针

再次简化:(在使用某个点之前才初始化它从左到右(从有到左)的最大值)
假设左右两边越往中间走值越大,所以在比较时最小值时,maxL < maxR,则表明此时的maxL小于 maxR往左走的所有值。

class Solution {
    public int trap(int[] height) {
        int left = 0, right = height.length - 1, res = 0;
        int maxL = height[left], maxR = height[right];
        while (left < right) {
            maxL = Math.max(maxL, height[left]);
            maxR = Math.max(maxR, height[right]);
            res += maxL < maxR ? maxL - height[left++] : maxR - height[right--];
        }
        return res;
    }
}

你可能感兴趣的:(算法,动态规划,算法,leetcode)