
贪心算法在 Go 里不是靠“写个模板”就能套用的,它本质是“排序 + 单次遍历”的组合技,核心在于选对排序维度和判断条件。
怎么选排序规则?看局部最优定义
贪心能否成立,取决于你定义的“当前最好”是否真能导向全局最优。比如:
-
findContentChildren:孩子胃口g和饼干尺寸s都升序——让最小的可用饼干喂最小胃口的孩子,避免浪费 -
canCompleteCircuit:不排序,而是用净油量gas[i] - cost[i]累积判断——起始点必须是第一个使累积值由负转非负的位置 -
lastStoneWeight:每次取最大两个,所以用heap(最大堆)或每次sort.Ints后取末尾——但后者 O(n²log n),实际应手写堆
错把“按身高排序”当成万能解(如误用于分发糖果),会导致逻辑断裂;贪心没有银弹,排序依据必须从问题约束里反推。
为什么 maxSubArray 不该用贪心?边界容易漏
很多人抄了「当前和
立即学习“go语言免费学习笔记(深入)”;
使用 uber-go/dig 在 Golang 中实现依赖注入——基于反射容器,提供 Provide/Invoke、dig.In/dig.Out 参数与结果对象,支持命名依赖等
- 它隐含假设:负数前缀永远拖累后续,所以可丢弃——这成立,但仅当目标是「连续」且「求和」
- 若题目改成「最多跳过一个元素的最大子数组和」,贪心立刻失效,必须上动态规划
- 输入全负时,
currSum = 0重置会错失唯一解,正确写法要初始化maxSum = nums[0]并在循环中更新
贪心不是“快就用它”,而是“证明局部最优可传递”之后才敢用;否则就是拿锤子找钉子。
sort.Slice 自定义排序写错,贪心直接崩
Go 的 sort.Slice 是贪心前置关键,但闭包里写错逻辑等于白干:
- 比较函数返回
true表示“i 应该排在 j 前面”,不是“i 比 j 大” - LeetCode 406:
sort.Slice(people, func(i, j int) bool { if people[i][0] != people[j][0] { return people[i][0] > people[j][0] }; return people[i][1] ——身高降序、位置升序,少一个分号或反向就全乱 - 浮点数或结构体字段比较时忘记处理相等情况,
sort可能 panic 或结果不稳定
建议所有自定义排序都加一两行注释,写明“谁在前、谁在后、为什么”,比调试快十倍。
贪心最危险的坑,是你以为自己在做选择,其实只是在给排序找借口——没想清楚“为什么结束时间早就该优先”,光写 sort.Slice(..., func() bool { return intervals[i][1] ,跑不过测试只是时间问题。

















