-
Notifications
You must be signed in to change notification settings - Fork 0
Group Anagrams step1-3 #13
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,145 @@ | ||
# Group Anagrams | ||
|
||
## Step1 | ||
|
||
### 考えたこと | ||
|
||
strを文字のリストにして要素が同じものを一緒とみなす | ||
setみたいな順番を考慮しないやつが良いか。setは重複が消えてしまうのでダメ。 | ||
ではdictか。[a, b, c] をkeyにして全ての要素を過不足なく含むものをvalueに入れる | ||
文字列の長さが全て同じであるという仮定はないので注意。 | ||
|
||
#### 誤回答 | ||
|
||
リストはkeyにできないらしい。可変であるため。tupleならできる | ||
sorted()の出力はリスト。tupleをリストに変えてから順序を出していた。 | ||
dict.values()の出力はdict.valuesでありlistではない。 | ||
|
||
#### dict.values() | ||
|
||
https://docs.python.org/3/library/stdtypes.html#dict.values | ||
https://docs.python.org/3/library/stdtypes.html#dictionary-view-objects | ||
|
||
dict.keys(), dict.values(), dict.items() の出力は Dictionary view objectというもの。 | ||
dictの変更を動的に反映して表示する | ||
|
||
```python | ||
class Solution: | ||
def groupAnagrams(self, strs: List[str]) -> List[List[str]]: | ||
character_to_word = {} | ||
for word in strs: | ||
characters_tuple = sorted(tuple(word)) | ||
if characters_tuple not in character_to_word: | ||
character_to_word[characters_tuple] = [] | ||
characrer_to_word[characters_tuple].append(word) | ||
return character_to_word.values() | ||
``` | ||
|
||
#### 正答 | ||
|
||
wordをlistにしてからsortしてtupleにするところが無理やり感がある。良いやり方はないのか | ||
- 計算量 | ||
- 時間計算量 | ||
- sorted:O(wlogw) | ||
- この時w = len(word)は高々100なのであまり気にせずとも大丈夫 | ||
- ループ:O(n) | ||
- n = len(strs) <= 10^4 | ||
- 空間計算量 | ||
- dictに保存するので O(n) | ||
|
||
```python | ||
class Solution: | ||
def groupAnagrams(self, strs: List[str]) -> List[List[str]]: | ||
characters_to_word = {} | ||
for word in strs: | ||
characters = tuple(sorted(list(word))) | ||
if characters not in characters_to_word: | ||
characters_to_word[characters] = [] | ||
characters_to_word[characters].append(word) | ||
return list(characters_to_word.values()) | ||
``` | ||
|
||
sortedは文字列に使った場合、個々が分けられたlistを返す。上のコードは `tuple(sorted(word))` で十分 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. sorted は iterable をソートしますね。str は iterable ですね。 |
||
|
||
#### sorted() | ||
|
||
<https://docs.python.org/3/library/functions.html#sorted> | ||
|
||
key: 要素に対してどのような関数をかませてから比較をするか | ||
reverse: 昇順か降順か | ||
## Step2 | ||
|
||
### 参考にしたもの | ||
|
||
https://github.com/Hurukawa2121/leetcode/pull/12/files/03cabb8f64fb0ff8da925922063bddfae954593b#diff-4fa0cdca65a411c66c6c945917a26313ab139d2114a0dd45f24fd2f86a4d14b3 | ||
|
||
やり方は大体同じ | ||
C++は dict.values()みたいなのが存在しないのかループを回してvalueを取得している | ||
|
||
https://github.com/t0hsumi/leetcode/pull/12 | ||
|
||
wordごとにどのcharacterが出現しているかを文字コードを使って数える方法がある | ||
- string.ascii_lowercase | ||
<https://docs.python.org/3/library/string.html#string.ascii_lowercase> | ||
|
||
全てのlowercaseを含む文字列 | ||
upper, digit, hexdigit(数字とA-Fの小文字および大文字), octdigits(0-7), punctuation, whitespace(空白と見做されるもの:スペース、タブ、改行、改ページ、縦のタブ), printable | ||
|
||
```python | ||
class Solution: | ||
def groupAnagrams(self, strs: List[str]) -> List[List[str]]: | ||
frequency_to_anagrams = defaultdict(list) | ||
for word in strs: | ||
frequency = Counters(word) | ||
lowercase_frequency = tuple( | ||
frequency[lowercase] for lowercase in string.ascii_lowercase | ||
) | ||
frequency_to_anagrams[lowercase_frequency].append(word) | ||
return list(frequency_to_anagrams.values()) | ||
``` | ||
|
||
出力の返し方 | ||
```python | ||
# t0hsumiさん | ||
return [values for values in characters_to_word.values()] | ||
# 自分 | ||
return list(characters_to_word.values()) | ||
``` | ||
characters_to_wordじゃなくてcharacters_to_anagramsの方がわかりやすいか? | ||
|
||
tuple(sorted(string))じゃなくてstr(sorted(string))でもいいのか。 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ここでstrを使った気持ちとしては、
みたいな流れです。charの出現の組み合わせという意味だとtupleの方が適当ですね。 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 詳しい解説ありがとうございます。参考になります。 |
||
|
||
str(sorted(string))と.join(sorted(string))は異なる | ||
<https://docs.python.org/3/library/stdtypes.html#str> | ||
str(object)は内部でtype(object).str(object)を呼ぶ。 | ||
https://docs.python.org/3/library/stdtypes.html#str.join | ||
iterableを受け取りstrを返す。iterableの中にnon-strがあるとエラーになる | ||
|
||
- 内包表記とジェネレーター式 | ||
https://docs.python.org/ja/3/tutorial/datastructures.html#list-comprehensions | ||
https://docs.python.org/3/reference/expressions.html#generator-expressions | ||
- リスト内包表記 | ||
- [...] | ||
- リストを返す | ||
- 全ての要素を一旦メモリに格納する | ||
- ジェネレーター式 | ||
- (...) | ||
- generator objectを返す | ||
- 要素が必要になるタイミングで一つずつ生成しメモリ効率が良い | ||
- 一度使うと要素が消費される | ||
|
||
## Step3 | ||
|
||
defaultdictを使ってみた | ||
変数名をcharacters_to_anagramsに | ||
sortした後strにするのは違和感があるのでtupleに変換 | ||
|
||
``` python | ||
class Solution: | ||
def groupAnagrams(self, strs: List[str]) -> List[List[str]]: | ||
characters_to_anagrams = defaultdict(list) | ||
for word in strs: | ||
characters = tuple(sorted(word)) | ||
characters_to_anagrams[characters].append(word) | ||
return list(characters_to_anagrams.values()) | ||
``` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
tupleに対して
_tuple
という接尾辞を持った変数名は冗長だと思っています。tupleであることを強調したいとのであればこれで良いと思います。
sorted_characters
などのほうがやろうとしていることに対して直截な名前で読みやすいです。There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
確かにsortedかtupleのどちらを入れるかと言われればsortedを変数名に入れた方が良いと感じました。
長いコードだと変数の型を忘れてしまうことがあるので型を名前に含める癖がついてます。