主题 4:攒青豆

80 阅读2分钟

当青训营遇上码上掘金

题目

主题 4:攒青豆

现有 n 个宽度为 1 的柱子,给出 n 个非负整数依次表示柱子的高度,排列后如下图所示,此时均匀从上空向下撒青豆,计算按此排列的柱子能接住多少青豆。(不考虑边角堆积)

725ef710a59944d49d0315bece7a1ac1_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png

以下为上图例子的解析:

输入:height = [5,0,2,1,4,0,1,0,3]  
输出:17  
解析:上面是由数组 [5,0,2,1,4,0,1,0,3] 表示的柱子高度,在这种情况下,可以接 17 个单位的青豆。

解题过程

1、根据题意,青豆均匀向下撒,所以青豆可以类比为水,不可能存在以下情况,即表面一定水平。

// 不可能出现的情况

| 。
| 。。
| 。。。|
| 。。。|

2、如果两侧存在更高的柱子,直接按更高的来计算,计算时需要减去被包含柱子所占的空间。

| 。。。。。|
| 。。。。。|
| 。| 。| 。|
| 。| 。| 。|

3、可以将柱子划分为两部分处理,即开始(第一个不为零的柱子)-最高、最高-结束(最后一个不为零的柱子),即要先找到最高点然后进行划分。当然可能出现最高点在两侧,这样划分结果只有一部分,计算这一部分即可。

4、根据以上3点可以编写代码:

    1. 先确认边界,分别是“第一个不是值不是0的下标”、“最后一个值不是0的下标”、“最高点的值”、“最高点的下标”
      // 寻找第一个不是值不是0的下标
      int first_not_zore = -1;
      // 寻找最后一个值不是0的下标
      int end_not_zore = -1;
      // 寻找最高点的值
      int max_height = 0;
      // 寻找最高点的下标
      int max_height_index = 0;
      // 根据height[],为上述4个变量赋值
      for(int i=0; i<height.length; i++){
          if(first_not_zore == -1 && height[i] != 0){
              first_not_zore = i;
          }
          if(max_height < height[i]){
              max_height = height[i];
              max_height_index = i;
          }
          if(height[i] != 0) {
              end_not_zore = i;
          }
      }
    1. 如果全部柱子都为零,则无需再计算了。
      // 若height[] 全部为零 
      if(first_not_zore == -1 ) return 0;
    1. 最后分两部分计算结果,开始(第一个不为零的柱子)-最高、最高-结束(最后一个不为零的柱子)
    // 最终可以接的res个单位的青豆
    int res = 0;
    // 将数组根据max_height_index划分为两部分,第一部分 first_not_zore ~ max_height_index
    int temp = first_not_zore;
    for(int i=first_not_zore; i<=max_height_index; i++){
      if( height[i] >= height[temp] ){
          for(int j=temp+1; j<i; j++){
              res += (height[temp] - height[j]);
          }
          temp = i;
      }
    }
    // 将数组根据max_height_index划分为两部分,第二部分 max_height_index ~ end_not_zore
    temp = end_not_zore;
    for(int i=end_not_zore; i>=max_height_index; i--){
      if( height[i] >= height[temp] ){
          for(int j=temp-1; j>i; j--){
              res += (height[temp] - height[j]);
          }
          temp = i;
      }
    }
    return res;

5、完整代码如下: