这是 LeetCode 2234. 花园的最大总美丽值 的 Go 实现。
---
核心思路回顾
1. 预处理:将所有 `flowers[i] > target` 的截断到 `target`,计算假设全部种满后的剩余花数 `left`
2. 特判:如果所有花园本来已 ≥ target,或可以全部种满,直接返回
3. 排序后,逆向枚举:后缀 `[i, n-1]` 种满到 target,前缀 `[0, i-1]` 用双指针求最大最小值
---
Go 代码
```go
package main
import (
"sort"
)
func maximumBeauty(flowers []int, newFlowers int64, target int, full int, partial int) int64 {
n := len(flowers)
// 预处理:截断到 target,并计算假设全部种满后的剩余花数
left := newFlowers - int64(n)*int64(target)
for i := 0; i < n; i++ {
if flowers[i] > target {
flowers[i] = target
}
left += int64(flowers[i])
}
// 所有花园本来就已经 >= target
if left == newFlowers {
return int64(n) * int64(full)
}
// 可以全部种满
if left >= 0 {
allFull := int64(n) * int64(full)
almostFull := int64(n-1)*int64(full) + int64(target-1)*int64(partial)
if allFull > almostFull {
return allFull
}
return almostFull
}
sort.Ints(flowers)
var res int64 = 0
var preSum int64 = 0
j := 0
// 枚举 i:后缀 [i, n-1] 种满到 target(完善花园有 n-i 个)
for i := 1; i <= n; i++ {
// 撤销 flowers[i-1] 的"种满"操作,把它还回前缀
left += int64(target - flowers[i-1])
// 剩余花数为负,说明连这个后缀都种不满,跳过
if left < 0 {
continue
}
// 双指针:扩展 j,看前 j 个花园能否被提升到同一水平
for j < i && int64(flowers[j])*int64(j) <= preSum+left {
preSum += int64(flowers[j])
j++
}
// 前 j 个花园的最大最小值(一定 < target,因为上面特判了)
avg := (left + preSum) / int64(j)
totalBeauty := avg*int64(partial) + int64(n-i)*int64(full)
if totalBeauty > res {
res = totalBeauty
}
}
return res
}
```
---
复杂度分析
项目 复杂度
时间 `O(n log n)` — 排序主导,枚举 + 双指针 `O(n)`
空间 `O(1)` 额外空间(原地排序)
---
关键点说明
要点 说明
`left` 的含义 假设全部种满到 `target` 后,剩余的花数(可能为负)
逆向枚举 从 `i=1` 开始,逐步把 `flowers[i-1]` 从"完善花园"移回"不完善前缀"
双指针 `j` 只增不减,维护前缀中可以被提升到同一水平的最小花园数量
`avg` 计算 `(left + preSum) / j` 表示前 `j` 个花园能被提升到的最大共同最小值
全满特判 即使能全满,也要比较"留一个到 `target-1`"是否更优(`partial` 可能很大)
> 参考:[灵茶山艾府题解](https://leetcode.cn/problems/maximum-total-beauty-of-the-gardens/solutions/1408882/)