42. Trapping Rain Water

Given n non-negative integers representing an elevation map where the width of each bar is 1, compute how much water it is able to trap after raining.

The above elevation map is represented by array [0,1,0,2,1,0,1,3,2,1,2,1]. In this case, 6 units of rain water (blue section) are being trapped. Thanks Marcos for contributing this image!

Example:

Input: [0,1,0,2,1,0,1,3,2,1,2,1]
Output: 6
当一道题答案都看不懂的时候是沮丧的,但这就是事实,还要继续努力,先把代码背过。
class Solution {
    public int trap(int[] height) {
        int res = 0, mx = 0, n = height.length;
        int[] dp = new int[n];
        for (int i = 0; i < n; ++i) {
            dp[i] = mx;
            mx = Math.max(mx, height[i]);
        }
        mx = 0;
        for (int i = n - 1; i >= 0; --i) {
            dp[i] = Math.min(dp[i], mx);
            mx = Math.max(mx, height[i]);
            if (dp[i] - height[i] > 0) res += dp[i] - height[i];
        }
        return res;
    }
}

Grandyang大佬的dp算法,明天看看dp算法的内容

http://www.cnblogs.com/grandyang/p/4402392.html

https://blog.csdn.net/u013309870/article/details/75193592

Brute force 可以看懂,原理还没搞明白

 int ans = 0;
    int size = height.size();
    for (int i = 1; i < size - 1; i++) {
        int max_left = 0, max_right = 0;
        for (int j = i; j >= 0; j--) { //Search the left part for max bar size
            max_left = max(max_left, height[j]);
        }
        for (int j = i; j < size; j++) { //Search the right part for max bar size
            max_right = max(max_right, height[j]);
        }
        ans += min(max_left, max_right) - height[i];
    }
    return ans;

index从1到size-2,取每个元素左边和右边最大数中的较小值,减去当前数,加起来就是。

08/06/2019
重新回顾,发现有另一种简单方法
先找到peak,再左右分别计算。左:先设定left_peak = 0, 从左往右,如果当前比leftpeak大就重置left_peak,否则说明当前比leftpeak小或相等,leftpeak - 当前就是当前trap的水。
同理 右:设rightpeak,从右往左,大就重置,小就更新trap的水。
public class Solution {
    public int trap(int[] A) {
        final int n = A.length;
        int peak_index = 0; // 最高的柱子,将数组分为两半
        for (int i = 0; i < n; i++)
            if (A[i] > A[peak_index]) peak_index = i;

        int water = 0;
        for (int i = 0, left_peak = 0; i < peak_index; i++) {
            if (A[i] > left_peak) left_peak = A[i];
            else water += left_peak - A[i];
        }
        for (int i = n - 1, right_peak = 0; i > peak_index; i--) {
            if (A[i] > right_peak) right_peak = A[i];
            else water += right_peak - A[i];
        }
        return water;
    }
};

 

posted @ 2019-01-30 09:21  Schwifty  阅读(155)  评论(0编辑  收藏  举报