当青训营遇上码上掘金
题目:
现有 n 个宽度为 1 的柱子,给出 n 个非负整数依次表示柱子的高度,排列后如下图所示,此时均匀从上空向下撒青豆,计算按此排列的柱子能接住多少青豆。(不考虑边角堆积)
以下为上图例子的解析: 输入:height = [5,0,2,1,4,0,1,0,3]
输出:17
解析:上面是由数组 [5,0,2,1,4,0,1,0,3] 表示的柱子高度,在这种情况下,可以接 17 个单位的青豆。
这是类似经典的计算雨水问题的问题。我们可以使用双指针法来解决。
具体做法是从两端分别向中间移动指针,维护左右两端的最大高度,每次比较左右两端的最大高度,将较小的那个减去当前柱子的高度就是当前柱子能接的青豆数量。依次计算每个柱子能接的青豆数量,累加起来即可得到总共能接的青豆数量。时间复杂度为 O(n)。
以下是javaScript 代码实现:
function trap(height) {
// 左右指针
let left = 0, right = height.length - 1;
// 左右两根最大柱子的高度
let leftMax = 0, rightMax = 0;
// 总的豆子数量
let ans = 0;
// 移动指针(当左指针小于右指针时)
while (left < right) {
// 当左边柱子的高度 < 右边柱子的高度时
if (height[left] < height[right]) {
// 移动左边的指针
if (height[left] > leftMax) {
leftMax = height[left];
} else {
ans += leftMax - height[left];
}
left++;
} else {
// 移动右边的柱子指针
if (height[right] > rightMax) {
rightMax = height[right];
} else {
ans += rightMax - height[right];
}
right--;
}
}
return ans;
}
运行流程解析
第一次:
leftMax = 0; left = 0; rightMax = 3; right = 7; ans = 0;
第二次:
leftMax = 0; left = 0; rightMax =3; right = 6; ans = 3;
第三次:
leftMax=0; left = 0; rightMax = 3; right = 5; ans = 5;
第四次:
leftMax=0; left = 0; rightMax = 3; right = 4; ans = 8;
第五次:
leftMax=0;left = 0; rightMax = 4; right = 3; ans = 8;
第六次:
leftMax=0;left=0;rightMax=4; right = 2; ans = 11;
第七次:
leftMax=0;left=0;rightMax=4; right=1; ans = 13;
第八次:
leftMax=0;left=0;rightMax=4; right=0;ans = 17;
第九次:
leftMax=0;left=0;rightMax=5;ans = 17;
结束
码上掘金链接:code.juejin.cn/pen/7199948…