directory

When I looked at the interview questions before, I saw a problem of receiving rain water. After discussing it with yellow duck, I felt it was very interesting. Here I share this solution with you. Later, I saw this problem in LeetCode with the number 42. If you are interested, you can do it.

Problem description

Given n non-negative integers representing the height diagram of each column of width 1, calculate how much rain can be caught by the columns aligned with each other after rain.

Example 1:

Input: height = [0,1,0,2,1,0,1,3,2,1,2,1,1

Example 2:

Height = [4,2,0,3,2,5

Can you think about what you would do if you faced this kind of problem?

Problem analysis

First we can draw the length of the column based on the array given.

So how do we determine how much rain we’re getting? Of course, both of them are high and the middle is low to store the water, and the shaded area below is where the water is stored.

So we need to do a count of the left and right highest water levels, using two auxiliary arrays

One is used to store the maximum amount of rain on the left and one is used to store the maximum amount of rain on the right.

Choose the smallest of the two as the amount of water to store

Subtract the height of your column, of course. The rest is just rain to catch.

The code

function trap(height) {
    if(! height.length)return 0;
    let left = []
    let right = []
    let lmax = rmax = 0
    let len = height.length
    let result = 0
    // Find the maximum amount of water
    for(let i = 0; i < len; i++) {
        lmax = Math.max(height[i], lmax)
        rmax = Math.max(height[len-i-1], rmax)
        left[i] = lmax
        right[len- i - 1] = rmax
    }
    // Calculate the smallest and add up
    for(let i = 0; i < len; i++) {
        result += Math.min(left[i],right[i]) - height[i]
    }
    return result
};
Copy the code

If you want to optimize your writing, you can use reduce on the second pass

function trap(height) {
    if(! height.length)return 0;
    let left = []
    let right = []
    let lmax = rmax = 0
    let len = height.length
    for(let i = 0; i < len; i++) {
        lmax = Math.max(height[i], lmax)
        rmax = Math.max(height[len-i-1], rmax)
        left[i] = lmax
        right[len- i - 1] = rmax
    }
    return height.reduce((prev, item, index) = > {
        return prev + Math.min(left[index],right[index]) - item
    }, 0)};Copy the code

Analysis of the

  • Time complexity O(n)
  • Space complexity O(n)

In fact, the storage of the values of the right array can be omitted, although both are O(n) space complexity, but also a small optimization point.

function trap(height) {
    if(! height.length)return 0;
    let left = []
    let lmax = rmax = 0
    let len = height.length
    let result = 0
    for(let i = 0; i < len; i++) {
        lmax = Math.max(height[i], lmax)
        left[i] = lmax
    }
    // traverse from back to front
    for(let i = len - 1; i >= 0; i--) {
        rmax = Math.max(height[i], rmax)
        result += Math.min(left[i],rmax) - height[i]
    }
    return result
};
Copy the code