go中实现贪心算法需明确每步选择及依据,核心是正确使用sort.slice:比较函数必须覆盖所有分支、避免float64精度问题、结构体字段名大小写敏感、二维切片排序需用sort.slice而非sort.ints,且须验证贪心适用性。

Go 里没有 greedy 函数,所谓“实现贪心算法”,本质就是写清楚「每一步选什么」和「凭什么这么选」——其余全是排序、遍历、边界判断这些基础动作。
怎么写 sort.Slice 的比较函数才不崩
贪心几乎离不开 sort.Slice,但闭包里一个逻辑错,整个结果就错,且不报错只给错答案。
-
return必须覆盖所有分支:比如身高降序 + k 升序,不能只写if people[i][0] != people[j][0] { return people[i][0] > people[j][0] },漏掉else分支会导致未定义行为 - 比较字段别用
float64存整数端点:时间戳、索引、区间坐标全用int,float64在大数时精度丢失,sort会把本该相等的两个值判成不等 - 结构体字段名拼错是静默错误:写成
intervals[i].end(小写)而实际定义是End(大写),编译过但运行时取零值,排序乱套 - 二维切片排序别直接套
sort.Ints:sort.Ints(intervals[0])只排第一行;真要按第二列排,必须用sort.Slice(intervals, func(i, j int) bool { return intervals[i][1]
遍历时的基准值怎么初始化才安全
贪心主循环往往就五六行,但初始化错一行,空输入、单元素、负数区间全崩。
- 别用
math.MaxInt64初始化lastEnd:当所有区间都是负数(如[-5,-2]),intervals[i].Start >= math.MaxInt64永远 false,第一个区间就被跳过 - 正确做法是:先判空
if len(intervals) == 0 { return 0 },再设lastEnd = intervals[0].End,计数器count = 1,然后从i = 1开始扫 - 端点相接是否合法,取决于题干区间定义:闭区间
[a,b]和[b,c]是合法不重叠,判断条件必须是intervals[i].Start >= lastEnd,写成>就漏解 - 结构体比二维切片更稳:定义
type Interval struct{ Start, End int },字段名明确、类型清晰,避免intervals[i][0]这种易错索引
为什么有些题看似能贪心,实际不能用
贪心不是“快就上”,而是得先确认问题具备无后效性的贪心选择性质——当前选完,子问题完全独立于历史选择。
-
maxSubArray表面可贪心(当前和currSum小于 0 就重置),但全负输入时会失效:若初始化currSum = 0,遇到[-1,-2,-3]全被重置,结果为 0;正确做法是maxSum = nums[0],并在循环中更新 -
coinChange用贪心仅在面额满足正则性时成立(如[1,5,10,25]),遇到[1,3,4]和目标 6,贪心选4+1+1=3枚,而最优是3+3=2枚,必须换 DP -
canCompleteCircuit不排序:它靠gas[i] - cost[i]累积和找第一个由负转非负的位置,排序会破坏环状依赖关系,贪心依据是净余量单调性,不是某个字段大小
真正卡人的永远不是循环怎么写,而是“为什么这一维必须升序”“为什么空切片要提前 return”“为什么相等情况必须显式返回 false”——这些细节不在代码里,在题干约束和数学证明中。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











