攒青豆解法

76 阅读2分钟

当青训营遇上码上掘金 攒青豆暴力解法

题目

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

image.png 图片来自juejin.cn/post/718775…

解法

具体解法用一句话来说就是一行一行算,怎么一行一行算呢?先想想,在n个宽度为1的柱子里,哪些地方才能接到青豆。其实看一下图就能看出来,在这个空间里,被柱子挡到的地方自然接不到青豆,所以依照这个特点,我们把这个空间划分成一行一行的,在每一行中,如果碰到了柱子,自然该空间点就没有办法接到豆子,如果在该行中,左右两点各有一个柱子块,则这左右两个柱子块中间就必然可以接到豆子。 整个思路就是,求第 i 层的豆,遍历每个位置,如果当前的柱子高度小于 i,并且两边有高度大于等于 i 的,说明这个地方一定可以接到豆子,豆子数量就可以加 1。

public class Main {
   public static void main(String []args) {
       // 柱子
      int[] height = new int[]{5,0,2,1,4,0,1,0,3};
      // 柱子高度的最大值
      int max = 0;
      // 找出柱子高度的最大值
      for(int i = 0;i < height.length;i++) {
          if(height[i] > max) {
            max = height[i];
          } 
      }
      
      // 答案
      int result = 0;
      // 从最大值遍历每层
          for(int i = max;i > 0;i--) {
          // 左侧柱子
              int left = -1;
              // 寻找右侧柱子
              for(int j = 0;j < height.length;j++) {
                  if(height[j] >= i) {
                      if(left == -1) {
                      left = j;
                  } else {
                      result += j - left - 1;
                        left = j;
                    }
                }
            }
        }
      System.out.println(result);
   }
}

这个算法的效率不是特别高,但是容易想到,动态规划算法或者单调栈算法会更加快捷,效率更高,也更容易实现。