go语言算法-接雨水

package main

import "fmt"

// 接雨水问题

// 给定一个整数数组
// 可以认定为下标为横坐标,值为纵坐标形成的凹槽
// 将雨水泼下时,如何将存储的雨水的总数计入
func main()  {
   arr := []int{0, 1, 0, 2, 0, 1, 2, 0, 4, 3, 0, 1, 0, 3, 1}
   total := rain(arr)

   fmt.Println(fmt.Sprintf("total=%v", total))
}


// 双指针方法,从左右两侧移动
func rain(arr []int) int  {

   // 雨水总数
   rainTotal := 0

   if len(arr) < 3 {
      return rainTotal
   }

   // 左右双指针
   L := 0
   R := len(arr) - 1

   // 左右最大值
   leftMax := 0
   rightMax := 0

   // 左指针小于右指针循环持续,当左右两个指针相撞则终止计算
   for L < R {
      // 左指针的值小于右指针,则左指针往右移
      // 左指针的值大于等于右指针,则右指针左移
      if arr[L] < arr[R] {
         // 如果当前值大于最大值,则最大值为当前值
         if arr[L] > leftMax {
            leftMax = arr[L]
         }

         // 如果最大值大于等于当前值,则计算出当前值与最大值的差值
         // 即为储水量
         if arr[L] <= leftMax {
            rainTotal += leftMax - arr[L]
         }
         L++
      }

      if arr[L] >= arr[R] {
         // 如果当前值大于最大值,则最大值为当前值
         if arr[R] > rightMax {
            rightMax = arr[R]
         }

         // 如果最大值大于等于当前值,则计算出当前值与最大值的差值
         // 即为储水量
         if arr[R] <= rightMax {
            rainTotal += rightMax - arr[R]
         }
         R--
      }
   }

   return rainTotal
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值