求青豆的总体积

116 阅读2分钟

求柱子之间青豆总体积

当青训营遇上码上掘金

要用青豆填满柱子之间的空隙,并找出青豆的体积,具体来说可以分为以下几个步骤:

  1. 从第一列开始,找出当前的柱子和下一列柱子之间的最大高度。
  2. 在步骤1中找到的高度处放一条水平线,然后找出两列高度与水平线高度的差。
  3. 在步骤2中找到的差值代表了在柱子之间的空隙中可以储存的青豆的数量。
  4. 对所有柱子之间的缝隙重复步骤1到3。
  5. 将每个缝隙中储存的青豆数量相加,就可以得出青豆的总体积。

例如,如果有5个高度为[2,1,4,5,2]的柱子,第一个缝隙的最大高度为2,所以要在高度为2的地方放一条水平线。两列的高度和水平线的高度之差为[0, 1, 2, 3, 0]。第一个缺口中的青豆的体积是1。对其余的缺口重复同样的步骤,以求出青豆的总体积。在这种情况下,青豆的总体积将是6。

在这个代码中,main函数返回两个整数的最小值,maxVolume函数将一个列的高度数组作为输入,并返回青豆的体积。主要的想法是保留两个指针,一个从左边开始,一个从右边开始,并将高度较小的指针向中间移动。柱子的高度和到目前为止发现的最大高度所形成的线的高度之间的差值就是可以储存在这个空隙中的青豆数量,这将累积到体积变量中。

package main

import "fmt"

func min(a, b int) int {
   if a < b {
   	return a
   }
   return b
}

func volume(height []int, left, right int) int {
   minHeight := min(height[left], height[right])
   width := right - left - 1
   sum := 0

   for i := left + 1; i < right; i++ {
   	if height[i] < minHeight {
   		sum += minHeight - height[i]
   	}
   }

   return sum * width
}

func sumVolumes(height []int) int {
   sum := 0
   n := len(height)

   for i := 0; i < n; i++ {
   	right := i + 1

   	for right < n && height[right] < height[i] {
   		right++
   	}

   	if right < n {
   		sum += volume(height, i, right)
   		i = right - 1
   	}
   }

   return sum
}

func main() {
   columns := []int{2, 1, 4, 5, 2}
   fmt.Println("Total volume :", sumVolumes(columns))
}