给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的一个字母异位词。
输入: s = "anagram", t = "nagaram" 输出: true 输入: s = "rat", t = "car" 输出: false
说明:
你可以假设字符串只包含小写字母
首先看到题目的意思就是说两个字符串的字母一样,只是位置可以不一样
而且说明也说了,只包含小写字母。
那我们可以通过对两个字符串里面的字符进行排序,如果排序后的两个字符串是一样的,那么就可以说这两个字符串是有效的
// 比较两个排好序的字符串是不是一样 func isAnagram(s string, t string) bool { var ss []string var ts []string for _, c := range s { ss = append(ss, string(c)) } for _, c := range t { ts = append(ts, string(c)) } sort.Strings(ss) sort.Strings(ts) return reflect.DeepEqual(ss, ts) // return stringSliceEqualBCE(ss, ts) } func stringSliceEqualBCE(a, b []string) bool { if len(a) != len(b) { return false } if (a == nil) != (b == nil) { return false } b = b[:len(a)] for i, v := range a { if v != b[i] { return false } } return true }
因为题目说了,字符串只包含小写字母,那我们就可以放心地对字符串进行foreach了
但是这个写法耗时非常严重。
- 两个for,O(n)
- 两个排序,O(Nlogn)
- 乍看起来是一个O(Nlogn)的时间复杂度,但是几个加起来,时间就非常不乐观了
还有另外一种方法就是,使用map把字符串的字符出现个数保存起来
// 用两个字典分别把两个字符串的字符出现个数保存起来 func isAnagram1(s string, t string) bool { var sMap = make(map[rune]int) var tMap = make(map[rune]int) for _, c := range s { sMap[c] = sMap[c] + 1 } for _, c := range t { tMap[c] = tMap[c] + 1 } return reflect.DeepEqual(sMap, tMap) }
这个写法是一个O(N)时间复杂度的写法,时间比上面那个写法提升了不少
说明:
你可以假设字符串只包含小写字母