当青训营遇上码上掘金 —— 攒青豆

69 阅读2分钟

当青训营遇上码上掘金……

第一次使用码上掘金,感受良多。下面先进入正文。

对于第四题攒青豆问题,其实就是接雨水问题。 具体的题解可以看力扣的42题接雨水题解区,包括有动态规划、双指针、单调栈等解决方法。这里我随便采用了暴力把他遍历出来了,更好的解法可以去leetcode上查看。

题目描述

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

image.png

样例解析

以下为上图例子的解析:

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

解题思路

我们可以把两个高度中间的地方,看作一个柱,一个柱能不能装青豆,能装多少青豆,取决于这个地方左右两侧的高度的较小者,找到最高峰。分别从左右遍历。正向遍历,当下一个峰小于当前峰,可以接青豆,同理反向遍历。

找到最高的柱子并拿到位置 l

arr_Max = arr[i];

l = i;

int arr_Max = arr[0];
for (int i = 0; i < arr.length; i++) 
{ 
    if (arr[i] > arr_Max) 
        {
            arr_Max = arr[i]; 
            l = i; 
        } 
 }

往 l 的两边分别遍历

for (int i = 1; i < l; i++) {}

for (int i = h.length - 2; i > l; i--) {}

for (int i = 1; i < l; i++) {//正向遍历
    if (h[i - 1] > h[i]) {
        f[i] = h[i - 1] - h[i];
        h[i] = h[i - 1];
    } else {
        f[i] = 0;
    }
}
for (int i = h.length - 2; i > l; i--) {//反向遍历
    if (h[i + 1] > h[i]) {
        f[i] = h[i + 1] - h[i];
        h[i] = h[i + 1];
    } else {
        f[i] = 0;
    }
}

代码实现

/**
 * 支持 import Java 标准库 (JDK 1.8)
 */
import java.util.*;

/**
 * 注意:目前 Java 代码的入口类名称必须为 Main(大小写敏感)
 */
public class Main {
    public static void main(String[] args) {
        int[] h = {5, 0, 2, 1, 4, 0, 1, 0, 3};
        int sum = 0;
        int l = 0;
        int[] f = new int[h.length];
        int[] arr = new int[h.length];
        if (h.length < 2) {//长度小于2,接不了
            System.out.println("0");
        }
        for (int i = 0; i < h.length; i++) {//找到最高峰
            arr[i] = h[i];
        }
        int arr_Max = arr[0];
        for (int i = 0; i < arr.length; i++) {
            if (arr[i] > arr_Max) {//
                arr_Max = arr[i];
                l = i;
            }
        }
        for (int i = 1; i < l; i++) {//正向遍历
            if (h[i - 1] > h[i]) {
                f[i] = h[i - 1] - h[i];
                h[i] = h[i - 1];
            } else {
                f[i] = 0;
            }
        }
        for (int i = h.length - 2; i > l; i--) {//反向遍历
            if (h[i + 1] > h[i]) {
                f[i] = h[i + 1] - h[i];
                h[i] = h[i + 1];
            } else {
                f[i] = 0;
            }
        }
        for (int i = 0; i < h.length; i++) {
            sum = sum + f[i];
        }
        
        System.out.println(sum);
    }
}