字母异位词分组

Posted by zhouqian on Wednesday, July 6, 2022

力扣 49. 字母异位词分组

给你一个字符串数组,请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。

字母异位词 是由重新排列源单词的字母得到的一个新单词,所有源单词中的字母通常恰好只用一次。


方案一:用长度为 26 的计数数组保存每个单词的字母出现次数,然后将其作为 key,用无序映射保存。(部分语言不支持)

func groupAnagrams(strs []string) (ans [][]string) {
    // 用数组作为 map 的 key (部分语言不支持)
    mp := make(map[[26]int][]string, len(strs))
    // 遍历 strs
    for _, str := range strs {
        // 定义长度为 26 的数组
        key := [26]int{} 
        // 遍历单词,将组成单词的字母的出现次数保存到数组
        for _, v := range str {
            key[v - 'a']++
        }
        // 将当前单词保存到 map 中
        mp[key] = append(mp[key], str)
    }
    
    for _, v := range mp {
        ans = append(ans, v)
    }
    return
}
  • 时间复杂度:O(n),因为需要遍历所有单词,所以时间复杂度为 O(n)。
  • 空间复杂度:O(n),因为使用了长度不超 n 的无序映射,所以空间复杂度为 O(n)。

方案二:将每个单词的组成字母排序,再将排序后的字母组成无序映射 map 的 key,遍历所有单词构建无序映射。

func groupAnagrams(strs []string) (ans [][]string) {
    // 定义无序映射
    // key 为将单词字母排序后重组成的字符串,val 为组成字母由 key 构成的单词集合
    mp := make(map[string][]string)

    // 遍历所有单词
    for _, str := range strs {
        // 将单词格式转化为字节数组(将单词拆分为字母)
        arr := []byte(str)
        // 使用自定义排序算法,使得所有组成单词的字母顺序排序
        sort.Slice(arr, func(i, j int) bool { return arr[i] < arr[j]})

        key := string(arr)
        mp[key] = append(mp[key], str) 
    }

    // 构建答案
    for _, v := range mp {
        ans = append(ans, v)
    }
    return 
}
  • 时间复杂度:O(n),因为需要遍历所有单词,所以时间复杂度为 O(n)。
  • 空间复杂度:O(n),因为使用了长度不超 n 的无序映射,所以空间复杂度为 O(n)。