用 map[string]struct{} 做哈希表比嵌套循环快 10–100 倍,时间复杂度从 O(n×m) 降至 O(n+m),但需注意内存占用和键类型限制。

直接结论:用 map[string]struct{} 做哈希表,比遍历嵌套循环快 10–100 倍;但要注意内存占用和键类型限制,别无脑套用。
为什么不用 for 循环两层嵌套求交集
常见错误是写成:for _, a := range arr1 { for _, b := range arr2 { if a == b { ... } } }。这种 O(n×m) 时间复杂度在数组长度超 10⁴ 就明显卡顿,10⁵ 级别基本不可用。
真实场景中,比如对比两个日志文件的 URL 列表(各 50 万条),纯循环可能耗时数秒甚至分钟;而哈希表方案通常控制在 50ms 内。
- 哈希表把查找降为平均 O(1),整体降到 O(n+m)
- Go 的
map[string]struct{}是最省内存的布尔标记方式(struct{}占 0 字节) - 字符串作为 key 安全——Go runtime 对 string 的哈希已优化,且支持相等比较
交集实现:用 map 做快速存在性判断
核心思路:把一个数组转成 map,再遍历另一个数组查 key 是否存在。
立即学习“go语言免费学习笔记(深入)”;
示例代码:
func intersect(a, b []string) []string {
set := make(map[string]struct{})
for _, s := range a {
set[s] = struct{}{}
}
var res []string
for _, s := range b {
if _, ok := set[s]; ok {
res = append(res, s)
}
}
return res
}
注意点:
Go 配置库,使用 spf13/viper — 分层优先级(flag > env >file > KV > default),提供 BindPFlag/BindPFlags、SetEnvPrefix + SetEnvKeyReplace 等功能。
- 不保证结果顺序——如果需要原顺序或排序,得额外处理(比如用
map[string]int记录索引) - 重复元素会被自动去重(因为 map key 唯一),这符合数学交集定义,但若业务需保留重复,就得换策略(如用
map[string]int计数) - 空字符串、含 control char 的 string 都能当 key,没问题;但 nil slice 或未初始化 map 会 panic
并集实现:合并 key 后取 map keys
并集本质是“所有不重复的元素”,map 天然去重,所以只需把两个数组都塞进同一个 map。
示例代码:
func union(a, b []string) []string {
set := make(map[string]struct{})
for _, s := range a {
set[s] = struct{}{}
}
for _, s := range b {
set[s] = struct{}{}
}
res := make([]string, 0, len(set))
for s := range set {
res = append(res, s)
}
return res
}
关键细节:
- 预分配
res容量(len(set))能减少扩容次数,对大集合有明显性能收益 - 遍历 map 得到的 key 顺序是随机的(Go runtime 故意打乱),不能依赖;如需确定顺序,必须显式
sort.Strings(res) - 如果两个数组本身含大量重复,先各自去重再 union 未必更快——map 插入本身就有判重逻辑,多一层预处理反而增加开销
大规模下容易被忽略的内存与边界问题
100 万字符串,每个平均 32 字节,map 底层至少要分配 200 万+ 桶(按负载因子 6.5 推算),实际内存占用常超 100MB。这不是算法问题,而是现实约束。
务必检查:
- 字符串是否真可比较?自定义结构体不能直接当 map key,除非实现
==且所有字段可比较;切片、map、func 类型禁止作 key - 是否需要并发安全?单 goroutine 场景用原生 map;多 goroutine 写入必须用
sync.Map或加锁,但sync.Map读快写慢,不适合高频写入场景 - 极端 case:如果字符串含大量长尾分布(比如 99% 是空串或相同值),哈希冲突会上升,map 性能退化——这时可考虑先统计频率,再针对性处理
真正卡住性能的,往往不是算法选错,而是没意识到 map 的内存开销和 key 类型限制。

















