当青训营遇上码上掘金
问题:攒青豆
现有 n 个宽度为 1 的柱子,给出 n 个非负整数依次表示柱子的高度,排列后如下图所示,此时均匀从上空向下撒青豆,计算按此排列的柱子能接住多少青豆。(不考虑边角堆积)
以下为上图例子的解析:
输入:height = [5,0,2,1,4,0,1,0,3]
输出:17
解析:上面是由数组 [5,0,2,1,4,0,1,0,3] 表示的柱子高度,在这种情况下,可以接 17 个单位的青豆。
思路分析
-
定义两个数,分别代表左右指针,分别对应左边和右边的数据,初始值分别为0和数组的长度减1
-
初始化两个值,分别对应左边和右边的最大值
-
通过左右最大值进行累加(通过列进行求),
只要p_right_max[i]>p_left_max[i],青豆高度将由 p_left_max 决定;同理p_right_max[i]<p_left_max[i],青豆高度将由 p_right_max 决定 -
变量:
p_left左指针,p_right右指针,p_left_max左指针的最大值,p_right_max右指针的最大值ans结果的值 -
判断条件:
height[p_left] < height[p_right]height[p_left] >= p_left_maxheight[p_right] >= p_right_max
代码
class Solution {
//双指针
public int trap(int[] height) {
//初始化变量
int p_left=0, p_right = height.length-1;
int p_left_max =0, p_right_max=0;
int ans = 0;
//循环左指针小于右指针
while(p_left < p_right){
boolean flag1=height[p_left] < height[p_right];
//判断最大值在右边还是左边
if(flag1){
//判断此时的左边是否为最大值
if(height[p_left] >= p_left_max){
p_left_max = height[p_left];
}else{
ans += (p_left_max - height[p_left]);
}
p_left++;
}else{
// 判断此时的右边是否为最大值
if(height[p_right] >= p_right_max){
p_right_max = height[p_right];
}else{
ans += (p_right_max-height[p_right]);
}
p_right--;
}
}
return ans;
}
}
结果: