diff --git a/49. Group Anagrams.md b/49. Group Anagrams.md new file mode 100644 index 0000000..ebfab7f --- /dev/null +++ b/49. Group Anagrams.md @@ -0,0 +1,93 @@ +49. Group Anagrams +Given an array of strings strs, group the anagrams together. You can return the answer in any order. + +Example 1: + +Input: strs = ["eat","tea","tan","ate","nat","bat"] + +Output: [["bat"],["nat","tan"],["ate","eat","tea"]] + +Explanation: + +There is no string in strs that can be rearranged to form "bat". +The strings "nat" and "tan" are anagrams as they can be rearranged to form each other. +The strings "ate", "eat", and "tea" are anagrams as they can be rearranged to form each other. +Example 2: + +Input: strs = [""] + +Output: [[""]] + +Example 3: + +Input: strs = ["a"] + +Output: [["a"]] + +Constraints: +1 <= strs.length <= 10^4 +0 <= strs[i].length <= 100 +strs[i] consists of lowercase English letters. +(https://leetcode.com/problems/group-anagrams/description/) + +--- +step1 +```py +class Solution: + def groupAnagrams(self, strs: List[str]) -> List[List[str]]: + key_to_char = {} + + for char in strs: + key = "".join(sorted(char)) + + if key not in key_to_char: + key_to_char[key] = [] + key_to_char[key].append(char) + return list(key_to_char.values()) +``` +strs.lengthをnとして、strs[i].length、つまり文字列の長さをkとする。 +時間計算量: for文をstrs.length回、回すのでO(n)、中でsortedするのにO(klogk)、joinで文字列に整えて出すのにO(k)、つまり全体でO(n*klogk) +空間計算量: 辞書でkeyとしてsortした文字列を入れているのでO(k)、valueにはもとの文字列を入れるのでO(k)、よって内部ではO(k)。for文をstrs.length回、回すのでO(k*n) + +時間計算量は、最悪10^4 * 2*10^2 * log10 で大体10^6 < 10^7なのでセーフ +key_to_charって名前で良いのか少し気になる。 + +--- +(https://github.com/komdoroid/arai60/tree/14ec1184d68b0514455e688bdfc2ef39e1d787d8/HashMap/49.GroupAnagrams) +を読んだ。 + +defaultdictだとキーがないときに、勝手に穴埋めしてくれるので、こっちを使ったほうが良さそう。 +リストを引数に入れたら、キーがないとき[]をvalueに入れてくれる。 +辞書の変数名はかなり長くなるけど、"sorted_str_to_words"にする。 + +step2 +```py +import collections +class Solution: + def groupAnagrams(self, strs: List[str]) -> List[List[str]]: + sorted_str_to_words = collections.defaultdict(list) + + for original_str in strs: + sorted_str = "".join(sorted(original_str)) + sorted_str_to_words[sorted_str].append(original_str) + return list(sorted_str_to_words.values()) +``` + +変数名を少し考えてつけてみたけど、長すぎて逆に可読性落ちていないか心配。 +また、タイポしそう。 + +step3 3回連続pass +```py +import collections +class Solution: + def groupAnagrams(self, strs: List[str]) -> List[List[str]]: + sorted_str_to_words = collections.defaultdict(list) + + for original_str in strs: + sorted_str = "".join(sorted(original_str)) + sorted_str_to_words[sorted_str].append(original_str) + return list(sorted_str_to_words.values()) +``` +見直しもしたが、意外とタイポなしでゼロから何回も書けた。 +変数名に意味があるから、書いていてコードの意味がより理解しやすくなった気がする。 +