【Brush questions diary】42. Catch the rain

Offer arrives, dig friends to pick up! I am participating in the 2022 Spring Recruitment Check-In Event, click to view the event details .

【Brush questions diary】42. Catch the rain

The 14th article of this writing diary is titled: 42. It is difficult to catch the rain

1. Topic description:

At first glance at this question, the title expression is also very simple and clear, but it is a difficult question

Is it true that the fewer questions are expressed, the more difficult the questions are ? But it should be alright, we reviewed the last article [Brushing Diary] 11. The container that holds the most water, it seems that these two problems are a bit similar, we can definitely solve it, let's take a look

2. Thought analysis:

1. What idea does this question examine? What is your thinking?

It doesn't matter, big brother, we can solve any problem. Even if we can't solve it for a while, we can study it and ask others for advice. In the end, we can always solve it. Believe in ourselves

The same is true at work, correct attitude, when encountering problems, think more about the logic and principles behind it, and strive to solve all the same types of problems in the future

Let's start by looking at what important information this question shows us:

  • First, this is a difficult question, and we should consider it as comprehensively as possible without feeling pressure .
  • Second, this is also a question of calculating the volume, which is slightly different from the previous [Brush Question Diary] 11. The container that holds the most water , but it depends on whether it can withstand rainwater, or it depends on the shortcomings.
  • Here we need to note that the length n of the array given by the title ranges from 1 to the 4th power of 10

Do we think this way to calculate rainwater?

Traverse from left to right, when the right side is higher than the left side, calculate the height difference, and then subtract the height of the column in the process

但是发现,其实逻辑这么纯粹是有问题的,因为右边的柱子并不都左边高,反之亦然,发现上图中,按照纯粹的逻辑是走不通的,中间可能存在我们考虑不周的场景和逻辑

那么我们思考一下,如果我们能有办法直接计算出某一列他能接多少单位的雨水,这样一来,处理起来岂不是更明确了?

如何来计算当前列到底能承接多少雨水呢?

还是这个原理,一个桶能装多少水,取决于短板,那么当前列是否可以承接雨水,能承接多少雨水,也取决于当前列,是否比左边和比右边短

则,我们可以看到如下的图演示

通过查看上图演示,我们知道当前列能承接多少雨水,只需要计算当前列的最左边的身高,最右边的身高,得到他们的最小值之后,再减去当前列自己的身高,即可计算出来

那么接下来,咱们就来简单的实现一下上述的思想吧,这个逻辑就很明确了,按照列来计算承接的雨水,然后对所有列求和

三、编码

根据上述逻辑和分析,我们就可以翻译成如下代码

编码如下:

func trap(height []int) int {
    // 计算每一列左边的最大高度
    leftMax := make([]int, length)
    leftMax[0] = height[0]
    for i:=1; i< length-1; i++ {
        leftMax[i] = max(leftMax[i-1], height[i])
    }
    // 计算每一列右边的最大高度
    rightMax := make([]int, length)
    rightMax[length-1] = height[length-1]
    for i:=length - 2; i>= 0; i-- {
        rightMax[i] = max(rightMax[i+1], height[i])
    }

    // 计算当前列的实际雨水单位数
    res := 0
    for i,h := range height {
       tmp := min(leftMax[i],rightMax[i])
       if tmp > h{
           // 当前列是短板的时候,才能承接雨水
            res += tmp - h
       }
    }
    return res
}

func max(a,b int)int{
    if a>b {
        return a
    }
    return b
}

func min(a,b int)int{
    if a<b {
        return a
    }
    return b
}
复制代码

上述就是根据思路实现的代码,思路清晰了,编码就是一个翻译的过程,考虑好各种场景,咱们实现起来就比较顺畅,可以减少返工和出现 bug 的风险

四、总结:

这题的时间复杂度和空间复杂度都是 O(n),原因是我们只需要遍历一次 height 数组,且我们引入的O(n) 级别的空间消耗

原题地址:42. 接雨水

今天就到这里,学习所得,若有偏差,还请斧正

欢迎点赞,关注,收藏

朋友们,你的支持和鼓励,是我坚持分享,提高质量的动力

好了,本次就到这里

技术是开放的,我们的心态,更应是开放的。拥抱变化,向阳而生,努力向前行。

我是小魔童哪吒,欢迎点赞关注收藏,下次见~

Guess you like

Origin juejin.im/post/7079718479661629470