攒青豆

60 阅读2分钟

当青训营遇上码上掘金

因为自己是后端,再认真看了并且了解活动规则以后,明白了后端建议去选择主题三和主题四,我就飞快的去看主题三和主题四的介绍,不过大体看了一下感觉主题四好像是比主题三简单一些,而且还有图更加直观了(根本不用自己画),所以就选了攒青豆这个主题。当我看到这个题的时候,其实动态规划和双指针都可以解决,不过对于我来说双指针是比较好理解的,所以在解决这个问题的过程中,使用的是双指针去解决这个问题。

解法

其实能装多少豆子,最直观的方法就是看每个柱子能装多少豆子,然后把每一个柱子能装的豆子数量加起来,而每个柱子能装多少,又取决于自身左右两边最高柱子的最小柱子和自身的高度。比如在给出的例子中,第三列的柱子高度是2,而左侧最高柱子的高度是第一列的柱子高度为5,右侧最高柱子的高度是第五列的柱子高度为4,所以第二列能装的豆子就是第五列的高度减去自身的高度即4-2也就是能装2个。所以从开始到最后遍历所有的柱子,求出每个柱子能够装多少豆子,然后再把所有的豆子加起来,最终的总和即为能够装的豆子。

注意

  1. 因为在题意理解过程中,第一列的柱子和最后一列的柱子其实是装不了豆子的,所以在实现的时候要排除这两种情况。
  2. 因为在解题过程中使用到的是数组,而数组下标是从零开始,所以为了方便理解,列号从零开始。

代码实现

public class Main {
   public static void main(String []args) {
        Scanner scanner =new Scanner(System.in);
        int n =scanner.nextInt();
        int height[] = new int[n];
        for (int i = 0; i < n; i++) {
            height[i]= scanner.nextInt();
        }
         System.out.println(qing(height));   
   }
   public static int qing(int[] height) {
        int sum = 0;
        for (int i = 0; i < height.length; i++) {
            if (i==0 || i== height.length - 1) 
            continue;

            int r = height[i]; 
            int l = height[i]; 
            for (int j = i+1; j < height.length; j++) {
                if (height[r] > r) 
                r = height[r];
            }
            for (int k = i-1; k >= 0; k--) {
                if(height[k] > l) 
                l = height[k];
            }
            int h = Math.min(l, r) - height[i];
            if (h > 0) sum += h;
        }
        return sum;
   }
}