当青训营遇上码上掘金-主题四攒青豆

66 阅读2分钟

当青训营遇上码上掘金

前言

非常高兴能够加入第五届青训营的后端之旅,希望能在学习实践过程中丰富自己的知识面,学到更多的后端知识,同时锻炼自己的实践能力,同时学到Go语言的基础用法和时间,与队友共同完成大项目的设计。此次我选择了主题四攒青豆的题目,小白有很多不足,文章有错误之处,请大家多多包涵。

题目介绍:

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

图片1.png

以下为上图例子的解析: 其中输入输出为:

输入:height = [5,0,2,1,4,0,1,0,3]  

输出:17  

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

题目分析

我们通过攒青豆的这个场景,输入输出和题目描述,结合之前的做题经验,可以发现这与leetcode的题目接雨水非常相似,因此本题按照接雨水的解题思路会得到正确答案。

实现思路

这道题的实现方法有很多种,本文主要介绍动态规划的解法。

其中动态规划的递推公式:

对于当前位置,左边的最高高度是前一个位置的左边最高高度和本高度的最大值。

即从左向右遍历:maxLeft[i] = max(height[i], maxLeft[i - 1]);

从右向左遍历:maxRight[i] = max(height[i], maxRight[i + 1]);

代码实现

完整代码链接:VfqOuuNS - 码上掘金 (juejin.cn)

public static void main(String []args) {
Scanner in = new Scanner(System.in);
while (in.hasNext()){
    String str = in.nextLine();
    String[] split = str.split(",");
    int[] heights = new int[str.length()];
  }
  System.out.println(trap(heights));
}

public int trap(int[] height) {
    int length = height.length;
    if (length <= 2) return 0;
    int[] maxLeft = new int[length];
    int[] maxRight = new int[length];
    // 记录每个柱子左边柱子最大高度
    maxLeft[0] = height[0];
    for (int i = 1; i< length; i++) maxLeft[i] = Math.max(height[i], maxLeft[i-1]);
    // 记录每个柱子右边柱子最大高度
    maxRight[length - 1] = height[length - 1];
    for(int i = length - 2; i >= 0; i--) maxRight[i] = Math.max(height[i], maxRight[i+1]);
    int sum = 0;
    for (int i = 0; i < length; i++) {
        int count = Math.min(maxLeft[i], maxRight[i]) - height[i];
        if (count > 0) sum += count;
    }
    return sum;
}

总结

通过这次的解题,我认为把道题目转化为熟悉的场景接雨水,可以用动态规划的解题思路,找到动态规划的递推公式完成题解。新人能力有限文章如有误请多多包涵。