秋招 - 算法 - 字母异位词分组

128 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第18天,点击查看活动详情 >>

一、题目描述 LeetCode - 49

给你一个字符串数组,请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。
字母异位词 是由重新排列源单词的字母得到的一个新单词,所有源单词中的字母通常恰好只用一次。
示例 1:

输入: strs = ["eat", "tea", "tan", "ate", "nat", "bat"]
输出: [["bat"],["nat","tan"],["ate","eat","tea"]]

示例 2:

输入: strs = [""]
输出: [[""]]

示例 3:

输入: strs = ["a"]
输出: [["a"]]

二、解题思路

本题要求将字母异位词组合在一起,既将单词按照组成字母进行分类,若单词字母组成相同则将其分为一类。可以使用map结构来进行分类,其中map的key为源单词的按照字母顺序进行重新排序的字母序列,value为由key的字母序列衍生的字母异位词的List集合。在创建map的键值对时可以使用getOrDefault()方法,若map中已经存在相应的键值对则返回键对应的值,并将字母异位词加入到List数组中,若不存在相应的键值对则创建并返回空的List数组。最终将map转换为数组返回。

三、代码

class Solution {
    public List<List<String>> groupAnagrams(String[] strs) {
        Map<String, List<String>> map = new HashMap<>();
        for (String str : strs) {
            char[] arr = str.toCharArray();
            Arrays.sort(arr);
            String key = new String(arr);
            List<String> list = map.getOrDefault(key, new ArrayList<String>());
            list.add(str);
            map.put(key, list);
        }
        return new ArrayList<List<String>>(map.values());
    }
}

四、总结

本题通过map进行单词分类,其时间复杂度:O(nklogk),其中 n 是 strs 中的字符串的数量,k 是 strs 中的字符串的的最大长度。需要遍历 n 个字符串,对于每个字符串,需要 O(klogk) 的时间进行排序以及 O(1) 的时间更新哈希表,因此总时间复杂度是 O(nklogk),空间复杂度:O(nk),其中 nn 是 strs 中的字符串的数量,k 是 strs 中的字符串的的最大长度。