当青训营遇上码上掘金
前言
非常高兴能够加入第五届青训营的后端之旅,希望能在学习实践过程中丰富自己的知识面,学到更多的后端知识,同时锻炼自己的实践能力,同时学到Go语言的基础用法和时间,与队友共同完成大项目的设计。此次我选择了主题四攒青豆的题目,小白有很多不足,文章有错误之处,请大家多多包涵。
题目介绍:
主题四攒青豆:现有 n 个宽度为 1 的柱子,给出 n 个非负整数依次表示柱子的高度,排列后如下图所示,此时均匀从上空向下撒青豆,计算按此排列的柱子能接住多少青豆。(不考虑边角堆积)
以下为上图例子的解析: 其中输入输出为:
输入: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;
}
总结
通过这次的解题,我认为把道题目转化为熟悉的场景接雨水,可以用动态规划的解题思路,找到动态规划的递推公式完成题解。新人能力有限文章如有误请多多包涵。