当前位置: 首页 > news >正文

千问 LeetCode 2973. 树中每个节点放置的金币数目 Go实现

以下是 LeetCode 2973. 树中每个放置的金币数目 的 Go 语言实现:

package main

import (
"sort"
)

func placedCoins(edges [][]int, cost []int) []int64 {
n := len(cost)
// 1. 建图 (邻接表)
g := make([][]int, n)
for _, edge := range edges {
u, v := edge[0], edge[1]
g[u] = append(g[u], v)
g[v] = append(g[v], u)
}

ans := make([]int64, n)
// 默认每个节点初始金币数为 1
for i := range ans {
ans[i] = 1
}

// 2. 深度优先搜索
var dfs func(node, fa int) []int
dfs = func(node, fa int) []int {
// 收集当前子树的节点索引
subtree := []int{node}

for _, neighbor := range g[node] {
if neighbor == fa {
continue // 无向树深搜防环,跳过父节点
}
sub := dfs(neighbor, node)
if len(sub) < 5 {
subtree = append(subtree, sub...)
} else {
// 只保留2个最小的和3个最大的
subtree = append(subtree, sub[0], sub[1], sub[len(sub)-3], sub[len(sub)-2], sub[len(sub)-1])
}
}

// 对当前子树的候选节点按 cost 排序
sort.Slice(subtree, func(i, j int) bool {
return cost[subtree[i]] < cost[subtree[j]]
})

// 如果节点数大于5,只保留极值
if len(subtree) > 5 {
subtree = []int{
subtree[0], subtree[1],
subtree[len(subtree)-3], subtree[len(subtree)-2], subtree[len(subtree)-1],
}
}

// 计算当前节点应放置的金币数
if len(subtree) >= 3 {
sz := len(subtree)
// 组合1: 两个最小的负数 * 最大的正数
prod1 := int64(cost[subtree[0]]) * int64(cost[subtree[1]]) * int64(cost[subtree[sz-1]])
// 组合2: 三个最大的正数
prod2 := int64(cost[subtree[sz-3]]) * int64(cost[subtree[sz-2]]) * int64(cost[subtree[sz-1]])

maxProd := prod1
if prod2 > maxProd {
maxProd = prod2
}

if maxProd > 0 {
ans[node] = maxProd
} else {
ans[node] = 0
}
}

return subtree
}

dfs(0, -1)
return ans
}

核心逻辑与 Go 语言特性说明:
1. 闭包与状态传递:在 Go 中,我们使用匿名函数 dfs 作为闭包,这样可以直接访问外部的 cost 数组和 ans 结果数组,避免了在函数参数中反复传递这些大数组,代码更加简洁。
2. 数学规律:要在一个包含正负数的数组中选出3个数使乘积最大,只有两种可能:
- 三个最大的正数
- 一个最大的正数和两个最小的负数
3. 剪枝优化:基于上述规律,我们在深度优先搜索(DFS)合并子树时,不需要保留所有的节点。每个子树最多只需要保留 2个最小的 和 3个最大的 节点(共5个)即可。这大幅降低了存储和排序的复杂度,使得时间复杂度维持在 O(N log N) 级别。
4. 防环处理:由于是无向树,DFS 时需要传入父节点 fa,遇到父节点直接跳过,防止走回头路形成死循环。
5. 结果计算:当子树节点数不足3个时,金币数保持初始值1;当大于等于3个时,取上述两种组合乘积的最大值,若为负数则放置0个金币。注意 Go 中 int 的乘法可能会溢出,计算乘积时使用了 int64 进行强转。

http://www.gsyq.cn/news/1476409.html

相关文章:

  • 别再为版本头疼了!手把手教你让CarSim 2020.0和MATLAB R2015a/R2016b成功‘牵手’
  • 分布式强一致性防线:深入 Raft 协议脑裂(Split-brain)场景的 Leader 选举与多版本并发控制(MVCC)数据修复
  • 前端新手福音:在快马平台用一句话生成你的第一个加载动画代码
  • ai辅助开发:借助快马平台智能生成win11开始菜单自定义设置工具
  • 2026年杭州公考/考公/公务员/省考/事业编/事业单位培训机构推荐榜单:专业师资与上岸率口碑之选 - 企业推荐官【官方】
  • 数据自主权实践:开源工具实现微信聊天记录永久保存与智能分析
  • AI 数字人直播系统深度测评:中小商家 7×24 小时直播的降本增效神器
  • 嵌入式Day25--多任务并发
  • 效率直接起飞 AI论文写作软件测评:2026年最新推荐与对比
  • 2026年小苏打厂家推荐:食品级/工业级小苏打源头企业,高纯度与环保生产工艺深度解析 - 品牌企业推荐师(官方)
  • 为什么多算一次反而更快?深入 Blackwell 微架构,拆解 FlashAttention-4 的逆天优化
  • 实战指南:基于快马AI在CentOS7上一键部署企业级GitLab服务器
  • 从零认知到精准投放,CSDN AI数字营销实战指南,7步打通获客-转化-复购全链路
  • Python 爬虫实战:百度地图POI数据爬取与商圈分析
  • 避开SBAS手动选GCP的坑:用PS-InSAR的自动参考点提升形变监测精度
  • 2026年 广东平模厂家实力解析:激光/吸塑/印刷/包装/精密平模及EVA/亚克力/汽车内饰平模源头工厂甄选 - 品牌企业推荐师(官方)
  • HoRain云--Codex 安装与使用
  • Go 语言构建高性能 AI 推理网关:从并发模型到流量调度的完整架构
  • 准备阶段2:PCIE LTSSM 链路训练与状态机详解
  • 微信+CSDN AI账号绑定冲突实录(2024年Q2真实踩坑报告):超限绑定触发风控的5个致命信号
  • 基于BQ76PL536A的电动汽车BMS设计:主动均衡与高精度采样实战
  • SPT-AKI存档编辑器终极指南:如何快速配置服务器路径并高效管理游戏存档
  • CSDN AI营销GEO内容收录真相(2024Q3最新实测数据):从发布到进入RAG知识库仅需11.3小时?还是被永久过滤?大模型语义抓取机制首度解密
  • 智能安防监控革命:Frigate NVR 实战部署与优化指南
  • 准备阶段1:Synopsys PCIE控制器典型数据通路梳理
  • 2026年 玻璃门锁五金推荐榜单:浴室夹/玻璃门吸/指纹锁/门夹/配件品牌厂家深度测评与选购指南 - 品牌企业推荐师(官方)
  • 跳出 AI 流水线写作桎梏:okbiye 以全链路定制化重构毕业论文撰写新范式
  • 文字秒变3D模型:这款AI设计工具颠覆你的CAD体验
  • 东营连锁品牌黄金回收门店TOP6排行榜 - 余生黄金回收
  • 2026北京迷你仓公司权威认定:北京贴心存五项标准逐项验证 - 企业深度横评dyy6420