接雨水最终版

150 阅读2分钟

我是个菜鸟

时隔这么长时间,我终于是将接雨水做出来了,呜呜呜

想了解曲折历程的可以看这两篇

篇一:当青训营遇上码上掘金 - 掘金 (juejin.cn)

篇二:攒青豆之接雨水|青训营笔记 - 掘金 (juejin.cn)

废话不多说,直接看思路,这个题最重要的思想就是动态规划,至于如何很好的利用动态规划,我还没有很好的理解,等再历练几题后再对动态规划进行总结。 好的,先把题目引过来

42. 接雨水 - 力扣(LeetCode)

image.png

这个接雨水啊,我想过从头看,想过从尾看,也想过从中间向两端看。这些显然是比较蠢的。

最终解题思想

动态规划的思想,就是动态的对结果进行修改,所以我们就从头看,一个一个的看。那每个位置的雨水量怎么看呢?我们都了解木桶效应吧,需要找最短板!!!在这我们不能直接拿每个位置的两端进行比较,因为,你看到的不一定是对的。因为每个位置可能顶上有水,所以我们需要动态的改变每个位置的高度。

所以我们就把开始位置后的最高位置当成是木桶的另一边,这里就用一个冒泡排序找

                high = start + 2;
                for (int i =start + 2;i < height.length;i++){//冒泡排序找到后面最大元素及其位置
                    if (height[i] > height[high])
                        high =i;
                }
            

从start + 2位置开始找,因为至少有一个间隔才能有雨水。

这里我选择start记录当前到达的位置,然后记录start + 1位置存储的雨水,这里要有一个判断,当start + 1位置高度小于两侧才能存储雨水

             if(height[start + 1] < Math.min(height[start], height[high])){
                result += Math.min(height[start], height[high]) - height[start + 1];
                height[start + 1] = Math.min(height[start], height[high]);
            }

然后对start进行自增,再进行这个过程,直到start到倒数第三个位置,这是最后一个可能有雨水的地方,用一个while循环即可。完整代码如下

class Solution {
    public int trap(int[] height) {
        int start = 0;
        int high = 0;
        int result = 0;
        while(start <= height.length - 3){
            if(start == high){
                high = start + 2;
                for (int i =start + 2;i < height.length;i++){//冒泡排序找到后面最大元素及其位置
                    if (height[i] > height[high])
                        high =i;
                }
            }
            if(height[start + 1] < Math.min(height[start], height[high])){
                result += Math.min(height[start], height[high]) - height[start + 1];
                height[start + 1] = Math.min(height[start], height[high]);
            }
            start++;
        }
        return result;
    }
}

这个题的解法灵感来自于它的孪生兄弟

11. 盛最多水的容器 - 力扣(LeetCode))

这个题的思想也是动态规划,如果是和我一样的算法小白可以先去做这个,做不出来看看答案,然后当你对动态规划有一定了解后可以尝试做接雨水,这个一定要多尝试,不要做几次就看答案。

这个题我是做了很长时间的,中间也是故意放开了一段时间,想着之后回来也许就有不同思想了,虽然有点笨,但这个是我独立做出来的还是很高兴的。

image.png

最后是我的一些感想

通过接触了一些动态规划的题目,我认为这类题暴力求解是无法解出的,时间复杂度太大了。再给你一个巨长巨长的数据,直接就宕了,所以我们思考问题不要太过死板。我现在这个解法其实也是比较慢的,有更好解法的小伙伴们欢迎来分享。