当青训营遇上码上掘金
因为自己是后端,再认真看了并且了解活动规则以后,明白了后端建议去选择主题三和主题四,我就飞快的去看主题三和主题四的介绍,不过大体看了一下感觉主题四好像是比主题三简单一些,而且还有图更加直观了(根本不用自己画),所以就选了攒青豆这个主题。当我看到这个题的时候,其实动态规划和双指针都可以解决,不过对于我来说双指针是比较好理解的,所以在解决这个问题的过程中,使用的是双指针去解决这个问题。
解法
其实能装多少豆子,最直观的方法就是看每个柱子能装多少豆子,然后把每一个柱子能装的豆子数量加起来,而每个柱子能装多少,又取决于自身左右两边最高柱子的最小柱子和自身的高度。比如在给出的例子中,第三列的柱子高度是2,而左侧最高柱子的高度是第一列的柱子高度为5,右侧最高柱子的高度是第五列的柱子高度为4,所以第二列能装的豆子就是第五列的高度减去自身的高度即4-2也就是能装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;
}
}