青训营 X 码上掘金 | ”攒青豆“题目解析

57 阅读2分钟

当青训营遇上码上掘金

题目简介

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

我的解决思路

看到这个题目,体内的DNA直接颤动了。这怎么这么熟悉,难道就是「接雨水」的翻版?

话不多说,直接开动。

把黑色的看作墙,给定一个数组,每个数代表从左到右的高度,求青豆的数量。

解法一:按行方式求解

整个思路就是,求第 i 层的青豆。如果当前高度小于 i,并且两边都有高度大于等于 i 的,说明这里可以接住青豆。

当求高度为i层的青豆时,先用一个 temp变量存储当前层的青豆。从左到右遍历柱子的高度,遇到高度大于i的时候,开始更新temp的值。当遇到高度小于i的就把temp1,遇到高度大于i的,把temp加到总和答案sum里面,把temp0,继续。

看第一层的青豆。此时数组是 [0, 5, 0, 2, 1, 4, 0, 1, 0, 3]

temp值初始化为0。当柱子高度大于等于当前层数1sum = sum + temp, temp = 0

height[0] = 0 < 1,不更新值。

height[1] = 5 >= 1sum = 0, temp = 0

height[2] = 0 < 1temp = temp + 1 = 1

height[3] = 2 >= 1sum = sum + temp = 1, temp = 0

height[4] = 1 >= 1sum = 1, temp = 0

height[5] = 4 >= 1sum = 1, temp = 0

height[6] = 0 < 1temp = temp + 1 = 1

height[7] = 1 >= 1sum = sum + temp = 2, temp = 0

height[8] = 0 < 1temp = temp + 1 = 1

height[9] = 3 >= 1sum = sum + temp = 3, temp = 0

所以在第一层,攒到了3颗青豆。

接下来看第二层的青豆。

height[0] = 0 < 2,不更新值。

height[1] = 5 >= 2sum = 3, temp = 0

height[2] = 0 < 2, temp = temp + 1 = 1

height[3] = 2 >= 2, sum = sum + temp = 4, temp = 0

height[4] = 1 < 2, temp = temp + 1 = 1,

height[5] = 4 >= 2, sum = sum + temp = 5, temp = 0

height[6] = 0 < 2, temp = temp + 1 = 1

height[7] = 1 < 2, temp = temp + 1 = 2

height[8] = 0 < 2, temp = temp + 1 = 3

height[9] = 3 >= 2, sum = sum + temp = 8, temp = 0

所以,截止到第二层,总共攒到8颗青豆。

以此类推,总共得到 17 颗青豆。

package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
)

func main() {
	var height []int
	stdin := bufio.NewReader(os.Stdin)
	line, err := stdin.ReadString('\n')
	if err != nil {
		fmt.Printf("err occured: %v", err)
	}
	str := strings.Fields(line)
	for _, h := range str {
		tmp, err := strconv.Atoi(h)
		if err != nil {
			continue
		}
		height = append(height, tmp)
	}
	n := len(height)
	sum := 0
	max := getMax(height) // 找到最大的高度
	for i := 0; i < max; i++ {
		isStart := false
		temp := 0
		for j := 0; j < n; j++ {
			if isStart && height[j] < i {
				temp++
			}
			if height[j] >= i {
				sum = sum + temp
				temp = 0
				isStart = true
			}
		}
	}
	fmt.Println(sum)
}

func getMax(height []int) (max int) {
	for _, h := range height {
		if h > max {
			max = h
		}
	}
	return
}

待定: 暂时先更新一种解法,其余解法之后还会在这里更新!