最直接变位词判断法是排序后比较:先检查长度,再将字符串转为rune切片,用sort.slice排序后比较。需用rune而非byte以正确处理unicode字符。

用 sort.Strings 排序后比较最直接
变位词(anagram)本质是字符频次完全相同、顺序不同的字符串。排序是最直观的解法:把两个字符串转成字符切片,排序后再拼回字符串比较。sort.Strings 不适用——它只处理 []string;正确函数是 sort.Sort 配合 sort.StringSlice,或更常用的 sort.Slice。
实操建议:
- 先检查长度,不等直接返回
false,避免无效排序 - 用
rune切片而非byte,否则会错误处理中文、emoji 等 Unicode 字符 - 示例:
func isAnagram(s, t string) bool { if len(s) != len(t) { return false } sr := []rune(s) tr := []rune(t) sort.Slice(sr, func(i, j int) bool { return sr[i]
用 map 计数适合大字符串或多次校验
排序时间复杂度是 O(n log n),而计数法是 O(n)。当字符串很长,或需在循环中高频调用时,map[rune]int 更优。注意:必须遍历两次(一次累加,一次抵消),且最后要确认 map 是否为空,不能只看是否所有值为 0——因为可能有未出现的键残留。
常见错误现象:for k := range count { if count[k] != 0 { return false } } 是错的,这会漏掉新增键没被遍历到的情况;正确做法是遍历 t 后再用 len(count) == 0 判断。
实操建议:
- 用
rune作 key,避免byte导致多字节字符被拆开 - 第一轮对
s计数,第二轮对t减数;遇到t中不存在的 rune 或减到负值,可提前返回false - 最终只需检查
len(count) == 0,比逐个判断值更安全
忽略大小写和非字母字符时要先归一化
实际业务中常要求“忽略大小写”“只比较字母”,比如 "Astronomer" 和 "Moon starer"。这时不能直接排序或计数,得先预处理。
Colly 是一个用于 Go 语言的快速开源爬取和爬虫框架。它适用于从简单的页面提取到异步爬虫处理大量页面集合,支持请求回调和结构化解析。
使用场景:用户输入昵称、密码提示、日志关键词匹配等。
实操建议:
- 用
unicode.IsLetter过滤非字母字符,再用unicode.ToLower统一小写 - 不要用
strings.ToLower全局转换——它对非 ASCII 字符行为不稳定,且无法过滤空格 - 避免在循环里反复调用
strings.TrimSpace或正则——性能差;一次性用strings.Map+ 匿名函数更高效
性能与兼容性:小字符串用排序,大文本用计数,别硬套算法题思路
LeetCode 上习惯用计数法,但真实 Go 服务中,短字符串(sort.Slice 更快——因为 map 分配、哈希计算、内存分配的开销可能超过排序本身。实测在 20 字符内,排序版比 map 版快 30%~50%。
容易踩的坑:
- 用
map[byte]int处理含中文的字符串,导致结果始终为false - 忘记检查
len(s) != len(t)就进循环,白费 CPU - 在 HTTP handler 中对用户输入反复做 anagram 判断却没加缓存或限流,被恶意构造长字符串拖垮 goroutine
真正关键的是根据输入特征选方法,而不是背模板。比如配置项校验、单元测试断言,用排序最省心;实时聊天消息敏感词检测,才值得上计数+预编译 rune 映射表。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










