1. 程式人生 > 其它 >18.leetcode - 49.Group Anagrams字母異位詞分組(hash、桶排序)

18.leetcode - 49.Group Anagrams字母異位詞分組(hash、桶排序)

技術標籤:程式設計題、演算法 - 個人積累總結

題目:

給定一個字串陣列,將字母異位詞組合在一起。字母異位詞指字母相同,但排列不同的字串。

示例:

輸入: ["eat", "tea", "tan", "ate", "nat", "bat"]

輸出:

[

["ate","eat","tea"],

["nat","tan"],

["bat"]

]

說明:

所有輸入均為小寫字母。

不考慮答案輸出的順序。

題目解析:

建立一個 26 長度的 counts 陣列(如果區分大小寫,我們可以建立 52 個,如果支援其他字元依次類推)。 然後我們給每一個字元一個固定的陣列下標,然後我們只需要更新每個字元出現的次數。 最後形成的 counts 陣列如果一致,則說明他們可以通過 交換順序得到。這種演算法空間複雜度 O(n), 時間複雜度 O(n * k), n 為陣列長度,k 為字串的平均長度。

key為頻次,value為符合該條件的字串的list;

複雜度分析

其中 N 為 strs 的長度, M 為 strs 中字串的平均長度。

  • 時間複雜度:$O(N * M)$

  • 空間複雜度:$O(N * M)$

public class GroupAnagrams {
    public List<List<String>> groupAnagrams(String[] strs) {

        // 先判空
        if(strs.length == 0) return new ArrayList<>();

        Map<String, List<String>> map = new HashMap<>(); // 建立對映關係
        for (String str : strs){ //遍歷該字串陣列
            int[] count = new int[26]; //建立一個 26 字母的對映關係
            for(char c : str.toCharArray()) count[c - 'a'] ++; // 遍歷字字串每個字母統計每個字母出現的頻次
            String key = Arrays.toString(count);//將頻次陣列轉為字串表示,並做為key
            if(!map.containsKey(key)) map.put(key, new ArrayList<>()); //如果 key 不存在, 新建對映關係
            map.get(key).add(str); //將符合條件的字串加入其對應的 Value 所在的陣列
        }

        return new ArrayList<>(map.values());
    }
}