您的位置:首页 > 文旅 > 美景 > leetcode算法题之接雨水

leetcode算法题之接雨水

2024/10/5 23:20:16 来源:https://blog.csdn.net/weixin_43160044/article/details/140645141  浏览:    关键词:leetcode算法题之接雨水

这是一道很经典的题目,问题如下:

题目地址

给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。

解法1:动态规划

动态规划的核心就是将问题拆分成若干个子问题求解,那这道题的问题实际上可以拆分为求x轴上每一块区域能承载多少雨水,而x轴上每一块区域能承载多少雨水取决于它左边和右边的最大高度值以及它的自身高度,所以我们可以先维护两个数组leftMaxArr和rightMaxArr

// height是leetcode传进来的高度数组leftMaxArr[i] = Math.max(leftMaxArr[i - 1], height)
rightMaxArr[i] = Math.min(rightMaxArr[i + 1], height)

leftMaxArr每一项对应着从左到当前区域高度的最大值,rightMaxArr就是从右到当前区域

知道了x轴上每一块区域的左右高度最大值后那这个子问题就很简单了,我们先定义一个子问题的结果数组result,那么公式可以这么写

result[i] = Math.max(leftMaxArr, rightMaxArr) - height[i]

最后将这个result数组的值加起来,就是本道题的结果了,当然,我们不需要使用到result数组,用一个变量维护即可,代码如下

/*** @param {number[]} height* @return {number}*/
var trap = function(height) {const len = height.lengthconst leftMaxArr = [], rightMaxArr = []let result = 0leftMaxArr[0] = height[0]rightMaxArr[len - 1] = height[len - 1]for (let i = 1; i < len - 1; i++) {leftMaxArr[i] = Math.max(leftMaxArr[i - 1], height[i])}for (let i = len - 2; i > 0; i--) {rightMaxArr[i] = Math.max(rightMaxArr[i + 1], height[i])}// 忽略 0 和 len - 1,因为它们是边界,不会有雨水for (let i = 1; i < len - 1; i++) {result += Math.min(leftMaxArr[i], rightMaxArr[i]) - height[i]}return result
};

解法2:双指针

这个解法是由解法一衍生而来,由解法一发现我们不需要同时知道左右的最大高度,只需要知道高度比较小的一侧,所以我们可以定义两个指针往中间收缩,每一次收缩的位置即为高度较小的一侧,这样就不用维护两个数组了,空间复杂度为O(1),代码如下:

/*** @param {number[]} height* @return {number}*/
var trap = function(height) {const len = height.lengthlet leftMax = height[0], rightMax = height[len - 1]let result = 0let left = 0, right = len - 1while (left < right) {// 此时leftMax一定小于rightMax,好比打擂台,强大的人可以一直打下去~if (height[left] < height[right]) {// 左侧为高度较小的一侧,对左指针当前位置用左侧最大高度进行计算result += leftMax - height[left]left++// 更新左侧最大高度leftMax = Math.max(leftMax, height[left])} else {result += rightMax - height[right]right--rightMax = Math.max(rightMax, height[right])}}return result
}

这样这个问题就完美解决啦,leetcode还有一种关于单调栈的解法,有兴趣的可以了解下~

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com