攒青豆

81 阅读2分钟

当青训营遇上码上掘金

前言

这是我参加「青训营 X 码上掘金」主题创作活动的文章创作,我选择了主题四“攒青豆”。
现在,我将以我的方式简单讲解一下如何简单的实现“攒青豆”。
当然,我的实现方式并不是唯一,也并不是那么完美,如有疑问可以指出。

代码

先看代码

package main

import "fmt"

func main(){
   var height =[]int{5,0,2,1,4,0,1,0,3}
   fmt.Println(trap(height))
}

func trap(height []int) int {
   n := len(height)
   left, right := 0, n-1
   leftMax, rightMax := 0, 0
   res := 0
   for left < right {
      if height[left] < height[right] {
         if height[left] >= leftMax {
            leftMax = height[left]
         } else {
            res += leftMax - height[left]
         }
         left++
      } else {
         if height[right] >= rightMax {
            rightMax = height[right]
         } else {
            res += rightMax - height[right]
         }
         right--
      }
   }
   return res
}

代码也发布在了码上掘金平台,点此访问

实现思路

代码比较简单,实现思路也很简单。

问题分析

攒青豆其实就是一个换了名字的求接收雨水问题,可以使用双指针算法解决。
对于每一对相邻柱子,找到它们之间的较小值,然后将它与两柱子间较矮的那一个的高度作差,并累加到结果之中。

算法解析

其实这个思路是有过优化的,并不是一开始就能想到的。
一个内能装下青豆的最大数量取决于两边柱子中较短的一边,而两根长柱子中间夹的短柱子并不影响关键。

代码实现

  1. 创建一个左指针和一个右指针,对切片进行遍历
  2. 将遍历中的最大值分别记录下来,用于后续的比较和计算
  3. 将每次的结果相加得到答案

总结

有待完善

当然,我的代码只是简单的实现了一个计算,对输入输出或是一些特殊情况都没有考虑,还可以提高不少,我列举几点:

  1. 格式化输入,而不是修改源代码
  2. 改进算法,优化效率
  3. 使用不同的方法来实现功能

最后,总结一下,这次活动不算太难,但对我一个对算法了解不多的人还算有挑战,有所收获。